【问题标题】:Can you parse sentences with `scanf` and detect newlines?你能用“scanf”解析句子并检测换行吗?
【发布时间】:2011-09-10 03:27:51
【问题描述】:

我知道如何使用scanf 将句子解析为单个单词:

while(1){
    scanf("%s", buffer)
    ...
}

但是,如果我输入像 one two three<return> 这样的句子,我如何在 while 循环中找出我进入缓冲区的单词是否是我按下 <return> 之前的单词?

我猜scanf几乎不可能,但也许有类似的功能?

【问题讨论】:

    标签: c parsing scanf


    【解决方案1】:

    您应该使用fgets() 读取整行,并像这样解析它:

    char buffer[BUFSIZE] = {};        // BUFSIZE should be large enough for one line
    fgets(buffer, BUFSIZE, stdin);    // read from standard input, same as scanf
    char *ptr = strtok(buffer, " ");  // second argument is a string of delimiters
                                      // can be " ,." etc.
    while (ptr != NULL) {
        printf("Word: '%s'\n", ptr);
    
        ptr = strtok(NULL, " ");      // note the NULL
    }
    

    检查当前单词是否是最后一个单词很简单:

    while (ptr != NULL) {
        char word[BUFSIZE] = {};
        strcpy(word, ptr);         // strtok clobbers the string it is parsing
                                   // So we copy current string somewhere else.
        ptr = strtok(NULL, " ");
    
        bool is_last_word = (ptr == NULL);
        // do your thing here with word[]
    }
    

    【讨论】:

    • 您依赖于知道行的长度不会超过 (BUFSIZE-1) 个字符。如果它更多,你最终会在 fgets() 调用中破坏单词。
    • 正确,因此我对此发表评论。唯一的另一种方法是使用动态分配的字符串缓冲区,这不在这个问题的范围内。此外,如果你这样做,你最好使用带有字符串流的 C++。
    【解决方案2】:

    如果您只对最后一个词感兴趣,您可以相当轻松地自行完成。如果行超过您的缓冲区大小,所提供的 fgets() 解决方案很容易变得复杂 - 您可能会在多个 fgets() 调用中拆分一个单词。你应该准备好应对这种可能性。

    scanf() 本身就很危险——它会将任意长度的单词读入你的缓冲区。如果您依赖它,请务必记住使用 %s 和长度说明符。我很确定你实际上不能使用 scanf() 来实现你所需要的。

    您最好逐个字符地处理输入。当你击中一个空格时,你就处于断字状态。当你点击换行符时,你就在最后一个字。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-28
      • 2022-06-14
      • 2017-12-23
      • 1970-01-01
      相关资源
      最近更新 更多