更改scanf()分隔符

时间:2012-10-14 19:15:59

标签: c scanf delimiter

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

有谁知道为什么?


这是我的代码:

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

5 个答案:

答案 0 :(得分: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);
}

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

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

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

这有助于您了解问题吗?


  

它适用于这种情况(对于单行)但如果我想将多行输入放入数组数组中,那么它就会失败。我不知道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); } 来处理该行。这会处理换行符,这是原始代码的垮台。

scanf()

问题:

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

  4. scanf()

    返回值

    #include <stdio.h> int scanf(const char * restrict format, ...); (来自ISO / IEC 9899:1999)的定义是:

      

    §7.19.6.4scanf函数

         

    概要

    scanf
         

    描述

         

    2 fscanf函数等同于stdin,其中插入了参数scanf   在scanf的参数之前。

         

    返回

         

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

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

答案 1 :(得分:3)

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

答案 2 :(得分:0)

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

希望这有助于......实际上&#34; \ n&#34;保留在流输入缓冲区中... Ee需要在再次调用scanf之前将其刷新

答案 3 :(得分:0)

我知道我迟到了,但我在很长时间后测试 C 后遇到了同样的问题。
这里的问题是新行被视为下一次迭代的输入。

所以,这是我的解决方案,使用 getchar() 丢弃输入流的换行符:

char s[10][25];
int i;

for(i = 0; i < 10; i++){
    printf("Enter string: ");
    scanf("%s", s[i]);
    getchar();
}

希望有帮助:)

答案 4 :(得分:0)

在循环中使用 scanf("%[^\n]", sen) 时,出现的问题是 \n 保留在输入缓冲区内并且没有被刷新。因此,下次使用相同的输入语法时,它会读取 \n 并将其视为空输入。解决此问题的一个简单但有效的解决方案是使用:

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

%*c 删除输入缓冲区中的 \n 字符。