4

代码:

#include <stdio.h>
int main(void) {
    char i[50];
    while(scanf("%s ", i)){
        printf("You've written: %s \n", i);
    }
    printf("you have finished writing\n");

    return 0;
}

一个问题是代码没有按预期执行。如果我输入:

abc def ghi.

它会输出:

You've written: abc
You've written: def

我该如何解决?目标是从标准输入读取每个单词,直到它到达“ENTER”或“。” (点)。

4

4 回答 4

5

@cnicutar 非常接近,但是您显然只想从空白以外的地方开始阅读,并且想在到达空白时停止阅读单个单词,因此对于您的扫描集,您可能想要更多类似的东西:

while(scanf(" %49[^ \t.\n]%*c", i)) {

在这种情况下,初始空格会跳过任何前导空格。然后扫描集读取,直到它到达空格、制表符、换行符或句点。然后 %*c 读取(但丢弃)下一个字符(通常是停止扫描的那个)。

但是,当/如果您到达缓冲区的末尾时,这可能会丢弃一个字符,因此您可能想要使用 %c,并提供一个要读入的字符。这将使您从一个比您提供的缓冲区更长的单词中恢复。

于 2012-04-13T21:02:27.237 回答
4

怎么样:

scanf("%49[ ^\n.]", str)

或类似的东西。

于 2012-04-13T20:57:51.340 回答
2

完全scanf放弃并使用fgets

while (fgets(i, sizeof i, stdin))
{
  printf("you've written: %s\n", i);
}

有以下注意事项:

  1. 如果目标缓冲区中有空间,fgets则将尾随换行符存储为输入的一部分;

  2. 如果您想停止阅读查找 a .,则必须添加一些逻辑以在输入字符串中查找它,例如:


    int foundDot = 0;
    while (fgets(i, sizeof i, stdin) && !foundDot)
    { 
      char *dot = strchr(i, '.');
      char *newline = strchr(i, '\n');

      if (dot != NULL)
      {
        foundDot = 1;
        *dot = 0; // overwrite the '.' character with the 0 terminator
      }

      if (newline != NULL)
      {
        *newline = 0; // overwrite newline character with 0 terminator
      }

      /**
       * Assuming you don't want to print a blank line if you find a dot
       * all by itself. 
       */
      if (strlen(i) > 0) 
        printf("you've written: %s\n", i);
    }
于 2012-04-13T22:20:35.300 回答
-1

最简单的方法是使用flex。否则,您将重复一堆困难、复杂的工作,并且很可能会犯错误。

另外,请阅读lex and yacc, 2nd edition

于 2012-04-13T20:56:39.317 回答