fscanf - linux fget




C编程:只从fgets打印int (5)

看到这个main

int main(void)
{
    int i;
    int ch;
    char str[512];
    fgets(str, sizeof str, stdin);

    for (i = 0; i <= (strlen(str)); i++)
    {
        if (str[i] != '\0' && str[i] != '\n')
        {
            int num = atoi(&str[i]);
            printf("%d\n", num);
        }
    }

    return 0;
}

我想从用户的数字,并获得所有的数字没有任何spacestabs

例如:

输入1 2 3 。 但在这种情况下,这个输出:

1
2
2
3
3

那么为什么我会收到23次?


strtok的解决方案也不是那么难:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
    char s[128];
    fgets(s, sizeof s, stdin);
    const char *delim = " \t\n";

    char *p = strtok(s, delim);
    while(p) {
        int val = strtol(p, NULL, 10);
        printf("%d\n", val);
        p = strtok(NULL, delim);
    }
    return 0;
}

虽然请记住,它使用隐藏状态有点有点(对于多线程程序不好),当然它会修改输入字符串,所以它不能是一个常量(但为什么你会那样做)。


atoi()ref

该函数首先丢弃尽可能多的空白字符(如在isspace中),直到找到第一个非空白字符。 [...]

这意味着,如果您将该功能作为输入“2”,则返回2。

改变这个:

if (str[i] != '\0' && str[i] != '\n')

对此:

if (str[i] != ' ' && str[i] != '\0' && str[i] != '\n')

你会得到:

1
2
3

这里有一个关于调试这个代码的提示:在你的输出中,你得到2和3两次,但不是1。

换句话说,你得到了一个空格之后的数字。 1之前没有空间。

这应该会让你觉得那里有空虚的东西。

事实上,即使str[i]是一个空格,你也可以进入if语句的主体。

通过添加一个条件来检查当前字符是不是空格,要进入if语句的boby,你实际上跳过空格。


因为你也传递了以空格开始的字符串的位置。 他们得到的第一个数字分别是23两次。 那是什么回报。

for (i = 0; i <= (strlen(str)); i++)
{
    if (str[i] != '\0' && !isspace(str[i]) )
    {
        int num = atoi(&str[i]);
        printf("%d\n", num);
    }
}

打印:

1
2
3

为了标记化的目的,你可以使用strtok并将其转换为数字strtol等。这些提供了比atol/atoi更好的错误情况控制。


当它到达输入的空格字符时,它会用" 2 3" (导致2)和后来的" 3" (导致3)调用atoi() ,从而产生意外的数字。


您可以使用ctype.h isdigitisalpha()函数(基于您的使用)。 以下是使用isdigit函数的代码片段:

for (i = 0; i <= (strlen(str)); i++)
{
    if (isdigit(str[i]))
    {
        int num = atoi(&str[i]);
        if(i && str[i-1]=='-') num *= -1;
        printf("%d\n", num);
        i += ( num==0 ) ? 1 : (int)log10(abs(num))+1;
    }
}

看到它在这里工作。
例如在这里检查isdigitisalpha()函数。

关于你的问题:

那么为什么我会收到2次和3次?

请参阅cplusplus.com上提供的以下说明,它解释了atoi()函数。

该函数首先丢弃尽可能多的空白字符(如在isspace中),直到找到第一个非空白字符。 然后,从这个字符开始,采用一个可选的初始加号或减号,后面跟着尽可能多的10位数字,并将其解释为一个数字值。







atoi