I know that strings are just an array of chars with adjacent memory addresses. So when you have a character array:
char s[5];
s[0] = '1';
s[1] = '2';
s[2] = '3';
s[3] = '4';
s[4] = '5';
and change character array at s[1] to "5" then printing such an array should return "15345". Now my question is about scanf and strtol functions. When I insert values into the array s using scanf twice using different sized strings, Why is it that the strtol function does not convert the ENTIRE array?
Here is my code as example:
#include <stdio.h>
#include <stdlib.h>
int main(){
char bytes[5];
printf("enter size 1: ");
scanf("%s", bytes);
printf("the size is: %ld\n", strtol(bytes, NULL, 10));
printf("enter size 2: ");
scanf("%s", bytes);
printf("the size is: %ld\n", strtol(bytes, NULL, 10));
return 0;
}
So imagine these user inputs:
10000
the program would then print out "the size is 10000"
then the user inputs:
100
the program then prints "the size is 100"
why doesn't it print out "the size is 1000" again? I only stored 100 into bytes, shouldn't the remaining array elements of bytes from the first input be unchanged and strtol should convert the rest of the array right?
In my mind, when the program stores the first input of 10000 into the array bytes, it looks like this at that moment
bytes = {1,0,0,0,0}
then when the user inputs 100, the array looks the same since it only changed the values of the first 3 elements and the rest of the array should remain the same:
bytes = {1,0,0,0,0}
with that strtol would convert the entire array to 10000 right?
Does scanf essentially "empty" out the rest of the array when storing values into the same memory address?
I know that strings are just an array of chars with adjacent memory addresses.
Not quite. In C, a string is also zero-terminated. That is, the string ends with the first character that has a zero value. For instance
char a[6] = { 'h', 'i', 0 , 'h', 'o', 0 }; // print(a) prints "hi"
char b[6] = { 'h', 'e', 'l', 'l', 'o', 0 }; // print(b) prints "hello"
char c[5] = { 'h', 'e', 'l', 'l', 'o' }; // print(c) will attempt to print "hello" followed by whatever characters happen to follow c[4] in memory, until it hits a zero value. But that may be reading outside the memory bounds of your application, or indeed your system, so anything can happen.
So when you have a character array:
<snip>
If you extend s
to char s[6]
and set s[5] = 0
, your assumptions about altering s[1]
and printing it will be correct
Now my question is about scanf and strtol functions. When I insert values into the array s using scanf twice using different sized strings, Why is it that the strtol function does not convert the ENTIRE array?
First a suggestion, after each scanf("%s", bytes);
line, insert the following:
printf("bytes = { %02x, %02x, %02x, %02x, %02x } (%02x)",
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5] );
Run your test code with that change, and check what that line prints.
If you see that, you'll hopefully see the answer to your question about scanf
and strtol
.
I'll annotate your code with some comments below indicating the contents of bytes
, using ?
as unknown :
#include <stdio.h>
#include <stdlib.h>
int main(){
char bytes[5];
printf("enter size 1: ");
scanf("%s", bytes); // 10000<return>
// bytes { ? , ? , ? , ? , ? } bytes[5] = ?
printf("the size is: %ld\n", strtol(bytes, NULL, 10));
// bytes { '1', '0', '0', '0',' 0' } bytes[5] = 0 !!! Note overflow
printf("enter size 2: ");
scanf("%s", bytes); // 100<return>
// bytes { '1', '0', '0', 0,' 0' } Note bytes[3] changes from '0' to 0
printf("the size is: %ld\n", strtol(bytes, NULL, 10));
return 0;
}
So in short,
Does scanf essentially "empty" out the rest of the array when storing values into the same memory address?
It doesn't empty it, but you're reading a string (format = "%s"
), so scanf will add the appropriate terminating zero at the end of the string you read in.