我知道字符串只是具有相邻内存地址的字符数组。所以当你有一个字符数组时:
char s[5];
s[0] = '1';
s[1] = '2';
s[2] = '3';
s[3] = '4';
s[4] = '5';
并将 s[1] 处的字符数组更改为“5”,然后打印这样的数组应返回“15345”。现在我的问题是关于 scanf 和 strtol 函数。当我使用 scanf 两次使用不同大小的字符串将值插入数组 s 时,为什么 strtol 函数不转换整个数组?
这是我的代码示例:
#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;
}
想象一下这些用户输入:
10000
然后程序会打印出“大小为 10000”
然后用户输入:
100
然后程序打印“大小为 100”
为什么不再打印“大小为 1000”?我只将 100 存储为字节,第一个输入中字节的剩余数组元素不应该保持不变, strtol 应该转换数组的其余部分吗?
在我看来,当程序将第一个输入 10000 存储到数组字节中时,那一刻是这样的
字节 = {1,0,0,0,0}
那么当用户输入 100 时,数组看起来是一样的,因为它只改变了前 3 个元素的值,而数组的其余部分应该保持不变:
字节 = {1,0,0,0,0}
使用 strtol 会将整个数组转换为 10000 对吗?
当将值存储到相同的内存地址时,scanf 是否本质上“清空”了数组的其余部分?
最佳答案
I know that strings are just an array of chars with adjacent memory addresses.
不完全是。在 C 中,字符串也是以零结尾的。也就是说,字符串以第一个具有零值的字符结尾。比如
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>
如果您将 s
扩展为 char s[6]
并设置 s[5] = 0
,您对更改 的假设s[1]
打印出来就是正确的
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?
首先是一个建议,在每个 scanf("%s", bytes);
行之后,插入以下内容:
printf("bytes = { %02x, %02x, %02x, %02x, %02x } (%02x)",
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5] );
使用该更改运行您的测试代码,并检查该行打印的内容。
如果您看到这一点,您将有望看到有关 scanf
和 strtol
问题的答案。
我将在下面用一些注释来注释您的代码,指出 bytes
的内容,使用 ?
作为未知:
#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;
}
简而言之,
Does scanf essentially "empty" out the rest of the array when storing values into the same memory address?
它不会清空它,但您正在读取一个字符串(格式 = "%s"
),因此 scanf 将在您读取的字符串的末尾添加适当的终止零.
关于c - 打印出字符串的整数表示时 Scanf 和 strtol 的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32936745/