如何在C的同一行中扫描字符串(带空格)和整数

时间:2018-11-19 05:13:02

标签: c scanf

我输入的是“ SAME AS 1”。在此,“ SAME AS”是字符串,“ 1”是整数。如果它们都在同一行中,我如何将它们都作为输入。

使用[^ \ n]并没有帮助,因为它还会将“ 1”作为字符串的一部分。使用[^ 0-9]也无济于事,因为相同的scanf命令将必须输入不以数字结尾的“ LEFT”或“ RIGHT”。

有没有一种方法可以将[^ \ n]和[^ 0-9]结合起来?还有其他方法吗?

P.S:无法更改输入。

1 个答案:

答案 0 :(得分:2)

scanf()不在乎换行符

到目前为止,您可以这样做:

#include <stdio.h>

int main(void)
{
    char buffer[64];

    int rc;
    int number;
    while ((rc = scanf("%63[^\n0-9]%d", buffer, &number)) != EOF)
    {
        if (rc == 0)
        {
            printf("Nothing read!\n");
            int c;
            while ((c = getchar()) != EOF && c != '\n')
                ;
        }
        else if (rc == 1)
            printf("Simple word - no number [[%s]]\n", buffer);
        else
            printf("Word and number [[%s]] %d\n", buffer, number);
    }
    return 0;
}

这将捕获并测试scanf()的结果。例如,给定数据文件:

SAME AS 1
LEFT
RIGHT

程序读取如下:

Word and number [[SAME AS ]] 1
Nothing read!
Simple word - no number [[LEFT]]
Simple word - no number [[RIGHT]]

也可以在“单词和数字”报告之后添加“字符吞噬”循环。最好创建一个微功能来做到这一点:

static inline void gobble(void)
{
    int c;
    while ((c = getchar()) != EOF && c != '\n')
        ;
}

首先在数据文件中添加一行,如下所示:

SAME AS 1
LEFT
RIGHT
123 ANGELS

您会得到:

Word and number [[SAME AS ]] 1
Nothing read!
Simple word - no number [[LEFT]]
Word and number [[RIGHT]] 123
Simple word - no number [[ ANGELS]]

scanf()函数家族几乎不关注换行符或其他空格,除非您强迫它们这样做。整个文件可以 也可以放在一行上,或者每组非空白都放在自己的行上,并且会产生几乎相同的输出。

您确实关心换行符

如果要基于行的输入,最好先读取行,然后解析结果。这还有一个好处,您可以更连贯地报告错误。例如:

#include <stdio.h>

int main(void)
{
    char line[4096];

    while (fgets(line, sizeof(line), stdin) != NULL)
    {
        char buffer[64];
        int number;
        int rc = sscanf(line, "%63[^\n0-9]%d", buffer, &number);
        if (rc == 0)
            printf("Nothing read! (line = [[%s]])\n", line);
        else if (rc == 1)
            printf("Simple word - no number [[%s]]\n", buffer);
        else if (rc == 2)
            printf("Word and number [[%s]] %d\n", buffer, number);
        else
            printf("sscanf() returned %d - can't happen (but did)?\n", rc);
    }
    return 0;
}

并在第一个文件上运行:

Word and number [[SAME AS ]] 1
Simple word - no number [[LEFT]]
Simple word - no number [[RIGHT]]

和第二个文件:

Word and number [[SAME AS ]] 1
Simple word - no number [[LEFT]]
Simple word - no number [[RIGHT]]
Nothing read! (line = [[123 ANGELS
]])

很难使用任何scanf()函数系列,并且要避免在SAME AS数据上留下尾随空格-除非您利用“两个单词加数字”或“一个单词加号”的优势数字”或“一个单词”,这将需要“读取行”示例(第二个程序),并使用sscanf()进行多次尝试。

scanf()函数家族非常非常非常难以准确使用。通常,读取一行并使用sscanf()可以降低复杂度,但是即使那样也并不完美。有关该主题的更多想法,请参见Beginner's Guide Away From scanf()