为什么scanf(“%i%1[\n]”,&a,&c)不能工作?

为什么scanf(“%i%1[\n]”,&a,&c)不能工作?,c,scanf,C,Scanf,在这里,我编写了以下代码来解析十六进制字符串并将其转换为十进制格式。在scanf中,我添加了char-type变量来存储由格式说明符%[\n]解析的内容,以调试程序 包括 包括 包括 int main{ INTA; 字符c; whiletrue { 如果扫描频率%i%1[\n],&a,&c!=EOF { printfa=%d;c=%d,a,c; } 其他的 { 打破 } } } 当我运行编译的执行性测试时,我得到了 据我所知,%i将匹配0xff,%1[\n]将匹配输入中未显示的\n。因此,结果将

在这里,我编写了以下代码来解析十六进制字符串并将其转换为十进制格式。在scanf中,我添加了char-type变量来存储由格式说明符%[\n]解析的内容,以调试程序

包括 包括 包括 int main{ INTA; 字符c; whiletrue { 如果扫描频率%i%1[\n],&a,&c!=EOF { printfa=%d;c=%d,a,c; } 其他的 { 打破 } } } 当我运行编译的执行性测试时,我得到了

据我所知,%i将匹配0xff,%1[\n]将匹配输入中未显示的\n。因此,结果将是a=255;c=10。那怎么了


另外,我在Linux上运行此代码。

您正在调用未定义的行为,因为%1[\n]向给定地址写入了2个字节,但您向其传递了一个只有一个字节空间的地址


实际上,可能发生的情况是写入&c的\n\0正在覆盖堆栈中的内容。但不值得去猜测未定义的行为。任何事情都有可能发生。避免它。使用char c[2]代替char c。并相应地修复对scanf的调用。

您正在调用未定义的行为,因为%1[\n]向给定地址写入了2个字节,但您向其传递了一个地址,该地址只有一个字节的空间

实际上,可能发生的情况是写入&c的\n\0正在覆盖堆栈中的内容。但不值得去猜测未定义的行为。任何事情都有可能发生。避免它。使用char c[2]代替char c。并适当地修复对scanf的调用。

在%1[\n]中的1是一个宽度限制,最多读取一个字符并保存在&a中

%1[\n]通过添加空字符成功完成后形成字符串。不幸的是,目的地只有一个空间-导致未定义的行为

%如果第一个字符不是“\n”,则1[\n]不会读取任何内容,也不会附加空字符。扫描停止。不匹配的输入仍保留在标准输入中

最好测试scanf所需的转换次数,而不是EOF

%1[\n]中的1是一个宽度限制,最多可在&a中读取和保存1个字符

%1[\n]通过添加空字符成功完成后形成字符串。不幸的是,目的地只有一个空间-导致未定义的行为

%如果第一个字符不是“\n”,则1[\n]不会读取任何内容,也不会附加空字符。扫描停止。不匹配的输入仍保留在标准输入中

最好测试scanf所需的转换次数,而不是EOF


欢迎来到SO。您应该始终检查scanf的返回值以匹配预期的参数数。如果仅检查EOF,则仅正确分析了1或0个参数,则无法捕获。@EricPostFischil我可以重现问题:Williams comment解决了问题:欢迎使用SO。您应该始终检查scanf的返回值以匹配预期的参数数。如果只检查EOF,则无法捕获正确解析的参数只有1个或0个。@EricPostpischil我可以重现问题:Williams comment解决了问题:为什么是两个字节\n是一个字符所有字符串都以null结尾。scanf将读取一个字节并写入2个字节。它将写入\n和\0以终止字符串。@alexis您忘记了终止字符\0了,谢谢。我还有一个问题。当我尝试scanf%I%1[],&a,&c-在[]中的一个空间时,它起了作用。根据我的理解,根据C语言,格式说明符中的空格只能匹配空格。因此\n将被放回流中。在下一次分析中,扫描%i%1[],&a,&c将尝试将%i匹配到\n,但将失败。但效果很好。您能解释一下吗?scanf没有使用%1[]的\n,因为它与转换说明符不匹配。但是%i使用前导空格,因此\n被它使用。为什么是两个字节\n是一个字符所有字符串都以null结尾。scanf将读取一个字节并写入2个字节。它将写入\n和\0以终止字符串。@alexis您忘记了终止字符\0了,谢谢。我还有一个问题。当我尝试scanf%I%1[],&a,&c-在[]中的一个空间时,它起了作用。根据我的理解,根据C语言,格式说明符中的空格只能匹配空格。因此\n将被放回流中。在下一次分析中,扫描%i%1[],&a,&c将尝试将%i匹配到\n,但将失败。但效果很好。您能解释一下吗?scanf没有使用%1[]的\n,因为它与转换说明符不匹配。但是%i使用前导空格,因此\n被它使用。
$./test_scanf
0xff
a = 0; c = 10
// char c;
char c[2];

while(true) {
    // if(scanf("%i%1[\n]", &a, &c) != EOF) {
    if(scanf("%i%1[\n]", &a, c) == 2) {
        printf("a = %d; c = %d", a, c);
    } else {
        break;
    }
}