更改scanf()分隔符

问题描述 投票:3回答:3

我的目标是将scanf的分隔符更改为“\n”。我尝试使用scanf("%[^\n]s",sen);并适用于单输入。但是当我在for循环中将相同的行放在多个句子中时,它给了我垃圾值。

有谁知道为什么?


这是我的代码:

char sen[20];
for (i=0;i<2;i++)
{
    scanf("%[^\n]s",sen);
    printf("%s\n",sen);
}
c scanf delimiter
3个回答
11
投票

考虑这个(C99)代码:

#include <stdio.h>

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

    while (scanf("%255[^\n]", buffer) == 1)
        printf("Found <<%s>>\n", buffer);
    int c;
    if ((c = getchar()) != EOF)
        printf("Failed on character %d (%c)\n", c, c);
    return(0);
}

当我运行它并输入一个字符串'绝对任何空格TABTABtabs嘉豪!'时,它给了我:

Found <<absolutely anything with   spaces       tabs galore!>>
Failed on character 10 (
)

当然,ASCII(UTF-8)1010是换行符。

这有助于您了解您的问题吗?


它适用于这种情况(对于单行)但如果我想将多行输入放入数组数组中则会失败。我不知道scanf如何在代码中返回一个值?

有许多(大多数?)经验丰富的C程序员避免像瘟疫那样的scanf()fscanf()的原因;他们太难以正常工作了。我推荐这个替代品,使用sscanf(),它没有得到与scanf()fscanf()相同的执行。

#include <stdio.h>

int main(void)
{
    char line[256];
    char sen[256];

    while (fgets(line, sizeof(line), stdin) != 0)
    {
        if (sscanf(line, "%255[^\n]", sen) != 1)
            break;
        printf("Found <<%s>>\n", sen);
    }
    int c;
    if ((c = getchar()) != EOF)
        printf("Failed on character %d (%c)\n", c, c);
    return(0);
}

这将读取输入行(使用fgets()确保没有缓冲区溢出(假设gets()函数,如果你听说过它,将你的计算机熔化到金属和硅池),然后使用sscanf()处理该行。处理换行符,这是原始代码的垮台。

char sen[20];
for (i=0;i<2;i++)
{
    scanf("%[^\n]s",sen);
    printf("%s\n",sen);
}

问题:

  1. 你不检查scanf()是否成功。
  2. 您在第一次迭代时将换行符保留在缓冲区中;第二次迭代生成返回值0,因为要读取的第一个字符是换行符,即扫描集排除的字符。
  3. 你看到的胡言乱语可能是第一行输入,重复。实际上,如果它不是有界循环,它就不会等你输入任何东西;它会一遍又一遍地吐出第一行。

Return value from scanf()

scanf()(来自ISO / IEC 9899:1999)的定义是:

§7.19.6.4scanf函数

概要

 #include <stdio.h>
 int scanf(const char * restrict format, ...);

描述

2 scanf函数相当于fscanf,其中stdin参数插入scanf的参数之前。

返回

3如果在任何转换之前发生输入故障,scanf函数将返回宏EOF的值。否则,scanf函数返回分配的输入项的数量,如果早期匹配失败,则可以少于提供的数量,甚至为零。

请注意,当我的第一个程序中的循环退出时,这是因为scanf()返回0,而不是EOF。


3
投票

%[^\n]将换行符留在缓冲区中。 %[^\n]%*c吃换行符。在任何情况下,%[^\n]都可以读取任意数量的字符并导致缓冲区溢出或更糟。我使用格式字符串%*[^\n]%*c来从文件中输出一行输入的剩余部分。例如,可以通过%d%*[^\n]%*c读取数字并丢弃该行的其余部分。如果在数字后面有注释或标签,或者不需要其他数据,这将非常有用。


0
投票
char sen[20];
for (i=0;i<2;i++)
{
  scanf("%[^\n]s",sen);
  printf("%s\n",sen);
  getchar();
}

希望这有帮助...实际上“\ n”仍保留在流输入缓冲区中... Ee需要在再次调用scanf之前将其刷新

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