C:为了奇怪的行为而逐位循环fgets

时间:2017-11-23 18:58:42

标签: c

我想实现简单的任务:

我使用numbers进行单行输入:

2 1 2 3

我想打印它,所以目前这适用于大多数场景:

char str[512];

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

    }
}

现在,如果我的输入带有number mote,那么一个digit事情开始变得混乱。

例如:

2 12

在这种情况下,我可以看到我有这个输入:

2 12 2

所以如果我有number > 9,我可以i 1提出if (i > 9) i++; :'

number

如果我的digits与3 i+=2有关,我可以fgets(str, sizeof str, stdin); char *ptr; long ret; for (i = 0; i < (strlen(str)); i++) { if (str[i] != '\0' && !isspace(str[i])) { ret = strtol(str[i], &ptr, 10); printf("%ld\n", ret); } } ,但还有另一种解决方案可能更“干净”吗?

修改

"isin"

1 个答案:

答案 0 :(得分:1)

您已经发现解决方案出了什么问题。你提出的想法很糟糕,如果字符串包含01之类的内容怎么办?这是两个字符,但仍然小于10.

有几种可能做得更好,我可以立即想到两种方法:

  • 而不是atoi(),请使用strtol()(无论如何应该)。 strtol()有一个参数endptr - 将char *指针的地址传递给它,然后此指针将指向未被转换的第一个字符。要使用它,您必须重写循环以使用指针。这是一个例子:

    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    char str[512] = "2 15 42 7 11";
    
    int main(void)
    {
        for (const char *c = str; *c;)
        {
            if (!isspace(*c))
            {
                char *endptr;
                long num = strtol(c, &endptr, 10);
                if (endptr == c) exit(1);   // nothing was converted, just error out here
                printf("%ld\n", num);
                c = endptr;
            }
            else
            {
                ++c;
            }
        }
    }
    
  • 更简单,如果在课程中销毁输入字符串无关紧要,请使用strtok()(请参阅the manpage了解其工作原理)拆分您在空白处的字符串,如第一次迭代中的strtok(str, " \t\n")和后续迭代中的strtok(0, " \t\n")。然后,您只需转换从strtok()获得的部分。