So, a lot of answers have already told you to use char str1[25];
instead of int str1[25]
but nobody explained why. So here goes:
A char
has length of one byte (by definition in C standard). But an int
uses more bytes (how much depends on architecture and compiler; let's assume 4 here). So if you access index 2 of a char
array, you get 1 byte at memory offset 2, but if you access index 2 of an int
array, you get 4 bytes at memory offset 8.
When you call gets
(which should be avoided since it's unbounded and thus might overflow your array), a string gets copied to the address of str1
. That string really is an array of char
. So imaging the string would be 123
plus terminating null character. The memory would look like:
Adress: 0 1 2 3
Content: 0x31 0x32 0x33 0x00
When you read str1[0]
you get 4 bytes at once, so str1[0]
does not return 0x31, you'll get either 0x00333231 (little-endian) or 0x31323300 (big endian).
Accessing str1[1]
is already beyond the string.
Now, why do you get a string length of 33? That's actually random and you're "lucky" that the program didn't crash instead. From the start address of str1
, you fetch int
values until you finally get four 0 bytes in a row. In your memory, there's some random garbage and by pure luck you encounter four 0 bytes after having read 33*4=132 bytes.
So here you can already see that bounds checks are very important: your array is supposed to contain 25 characters. But gets
may already write beyond that (solution: use fgets
instead). Then you scan without bounds and may thus also access memory well beyond you array and may finally run into non-existing memory regions (which would crash your program). Solution for that: do bounds checks, for example:
// "sizeof(str1)" only works correctly on real arrays here,
// not on "char *" or something!
int l;
for (l = 0; l < sizeof(str1); ++l) {
if (str1[l] == '\0') {
// End of string
break;
}
}
if (l == sizeof(str1)) {
// Did not find a null byte in array!
} else {
// l contains valid string length.
}
main()
returnsint
, you're strange to havereturn 0;
but declare it asvoid
.