【问题标题】:How to use fgets() function so that it only reads 12 characters per line?如何使用 fgets() 函数使其每行仅读取 12 个字符?
【发布时间】:2020-02-17 02:48:15
【问题描述】:

我有一个包含以下单词的文件:

Theendsherethiswillnotjaksdjlasdfjkl;asdjfklasdjfkl;asdfjl;
these
are
the

下面是我的代码:

int i = 0;
    bool duplicateFound = false;
        while(fgets(line,12,fp)){
            for (int j = 0; j < i; j++){
                if (strcmp(wordList[j], line) == 0){
                    duplicateFound = true;
                    printf("Duplicate Found on Line %d : %s\n", j, wordList[j]);
                }
            }
            if (duplicateFound == false){
                strcpy(wordList[i], line);
                printf("%s", wordList[i]);
            }
            i++;*/

            printf("%s", line);
        }

我使用 line 来保存每个单词,以便以后检查它是否在数组中重复。 我想要它,这样该函数每行最多只能读取 12 个字符,但它会输出以下输出。

实际输出:

Theendsherethiswillnotjaksdjlasdfjkl;asdjfklasdjfkl;asdfjl;
these
are
the

预期输出:

Theendsheret
these
are
the

【问题讨论】:

  • 最好贴出可编译的代码。
  • fgets(line, sizeof line, fp); line[12] = '\0' 有什么问题?
  • 如果你想用 fgets 读取最多 12 个字符,那么你必须使用 13 作为缓冲区的长度(记住你必须为字符串末尾的 '\0' 留出空间。如果您想忽略一行 12 个字符之后的字符,那么您还需要检查缓冲区中的 '\n'。如果您没有看到它,那么您需要读取并跳过字符,直到您读取结尾行或文件的结尾。
  • 有没有一种简单的方法可以在 12 之后丢弃其他字符?
  • @WilliamPursell 会丢弃之后的字符并移至下一行吗?

标签: c function fgets


【解决方案1】:

您确实应该只调用 fgets 然后执行 line[12] = '\0',但这并不能完全处理具有长行的输入。一种选择是如果 fgets 返回部分行(例如,如果 strchr(line, '\n') 返回 NULL)则简单地中止。 如果要处理长行,可以使用 getchar 丢弃数据,直到看到换行符。假设您不想将换行符视为 12 个字符之一,您可以执行以下操作:

#include <stdio.h>
#include <string.h>

int
main(void)
{
        char line[13];
        while( fgets(line, 13, stdin) ) {
                char *c = strchr(line, '\n');
                int ch;
                if( c == NULL ) while( (ch = getchar()) != EOF ) {
                        if( ch == '\n' ) {
                                break;
                        }
                } else {
                        *c = '\0';
                }
                if( printf("%s\n", line) < 0 ) {
                        break;
                }
        }
        return ferror(stdout) || ferror(stdin) || fclose(stdout) || fclose(stdin);
}

【讨论】:

  • 那么我可以在我的单词列表数组中保存“line”吗?
  • 你可以对数据做任何你想做的事情。将其保存到 wordlist 数组当然是一种可能性。
  • 您仍然需要使用 strcpyline 将在循环的每次迭代中被覆盖。
  • fclose(stdout) || ferror(stdout) || ferror(stdin) 很有趣。当fclose()失败为“无论调用是否成功,流与文件解除关联”,后续使用ferror(stdout)为UB。
  • @NeelPatel 您需要更具体地描述您遇到的错误。如果您发布完整的代码,将我的答案合并到您的代码中以执行您想要的操作可能非常简单。在您发布完整代码之前,任何调试代码的尝试都注定要失败。
猜你喜欢
  • 1970-01-01
  • 2018-05-28
  • 1970-01-01
  • 2022-11-17
  • 1970-01-01
  • 1970-01-01
  • 2015-12-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多