从字符串中获取整数

问题描述 投票:0回答:5

我有一些代码在

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

c while-loop scanf c-strings conversion-specifier
5个回答
2
投票
  1. 总是格式化你的代码。不适合我们 - 适合您自己
  2. alays检查scanf的结果
  3. 不要使用
    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;
}

https://godbolt.org/z/dcqc47vh1


2
投票

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;
}

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;
}

0
投票

你有几乎正确的方法:你应该用

fgets()
读取一行输入,然后用
sscanf()
解析它以提取整数。

按照编码,用

scanf("%s", a)
阅读既不正确又有风险:

  • 不正确,因为只读了一个单词,
    name
    ,然后是下一个循环中的
    1
  • 有风险,因为任何超过 19 个字符的单词都会导致缓冲区溢出。

这是一个简单的选择:

#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


-1
投票

您的输入是“name 1”,所以 sscanf 的第一次读取不是“成功的”,因为它首先读取的是“name”而且它也不是整数,按照建议尝试检查您有多少成功读取或(如果您相信输入)尝试

sscanf("%s %d", a, &p);

现在 sscanf 将知道跳过字符串并读取您想要的整数。

© www.soinside.com 2019 - 2024. All rights reserved.