我有一些代码在
name 1
循环中读取 while
形式的字符串,然后我必须提取整数值以打印是或否。但是当我尝试用sscanf
来做时,它只在循环完成后才给目标整数值。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
char a[20];
int p = 0;
while (scanf("%s", a)) {
sscanf(a, "%d", &p);
if (p != 0) {
printf("yes");
} else {
printf("no");
}
}
return 0;
}
即使我输入的字符串的整数大于
1
,程序总是打印no
.
我尝试用 printfs 评估输出,我看到当我执行它时给出了这个输出:
printf("%d", p);
对于输入:
name 1
它打印:
0no1yes
正如我所说,它首先得到整数为
0
,在输入if
后它变成了1
。
scanf
来阅读台词——总是使用fgets
int main(void)
{
char a[20];
int p=0;
while(fgets(a, sizeof(a), stdin))
{
if(sscanf(a,"%d",&p) != 1)
{
printf("\nNo no no!!!!\n");
continue;
}
if(p!=0)
{
printf("yes\n");
}
else{
printf("no\n");
}
}
return 0;
}
在
scanf
的呼唤中
while(scanf("%s",a)) {
转换说明符
s
允许只读取由空格分隔的文本。那就是如果你会进入
name 1
然后
scanf
的第一次调用将只读取文本 "name"
并且在循环的下一次迭代中 scanf
的调用将读取确实可以转换为整数的文本 "1"
。
需要在
scanf
的调用中使用另一个转换说明符。
while循环中的条件
while(scanf("%s",a)) {
事实上你有一个无限循环。
您的程序还包含冗余的 include 指令。
程序可以如下所示
#include <stdio.h>
int main( void )
{
char a[20];
while ( scanf(" %19[^\n]",a ) == 1 )
{
int p = 0;
sscanf( a,"%*s%d", &p );
if ( p )
{
puts( "yes" );
}
else
{
puts( "no" );
}
}
return 0;
}
当您使用
scanf()
从标准输入流读取输入值时,它会将输入值存储在缓冲区中,直到读取所有预期的输入值。如果您没有使用缓冲区中的所有输入值,它们可能会保留在缓冲区中,并可能导致您的程序出现问题。因此最好使用fgets()
方法从输入流中读取数据。
#include <stdio.h>
int main(){
char inpt[20];
char str[20];
int val=0;
while(1){
fgets(inpt, 20, stdin);
sscanf(inpt, "%s %d", str, &val);
if(val!=0){
printf("yes\n");
}
else{
printf("no\n");
}
}
return 0;
}
你有几乎正确的方法:你应该用
fgets()
读取一行输入,然后用 sscanf()
解析它以提取整数。
按照编码,用
scanf("%s", a)
阅读既不正确又有风险:
name
,然后是下一个循环中的1
。这是一个简单的选择:
#include <stdio.h>
int main(void) {
char a[100];
while (fgets(a, sizeof a, stdin)) {
int p;
if (sscanf(a, "%*s%d", &p) == 1 && p != 0)
puts("yes");
else
puts("no");
}
return 0;
}
但是请注意,上面的代码将接受可能无效的行,例如
Hello 1 world!
和 1 2 3
您的输入是“name 1”,所以 sscanf 的第一次读取不是“成功的”,因为它首先读取的是“name”而且它也不是整数,按照建议尝试检查您有多少成功读取或(如果您相信输入)尝试
sscanf("%s %d", a, &p);
现在 sscanf 将知道跳过字符串并读取您想要的整数。