【问题标题】:How can I read different lines of a text file with fgets?如何使用 fgets 读取文本文件的不同行?
【发布时间】:2021-12-27 21:53:39
【问题描述】:

例如,如果 .txt 有

你好
在那里。

写在里面,不管fgets(str, N, file)中的N再大,它只会在str中存储“Hello”,因为它会在找到'\n'字符时停止。

那么,例如,如果我想在其中找到一个特定的单词,我该如何读取整个文件?

【问题讨论】:

  • fgets 在到达换行符或 EOF 时停止读取,您需要在循环中调用 fgets 直到 EOF (或者您想读取多少行)。它读取的下一行将覆盖str 中读取的最后一行,因此您需要在读取下一行之前保存/处理/对刚刚读取的行执行任何操作。
  • 查看this answer,它在循环中使用fgets
  • 一种方法是找到文件的大小,分配一个大小为+1的缓冲区,然后fread将整个文件放入缓冲区,然后在返回的索引处写入nul终止符fread。然后申请strstr。您可能还想在搜索之前对整个缓冲区进行大小写转换。
  • 逐行读取文件并在读取的每一行中搜索单词。必须是 12-15 行代码。
  • 有没有可能是你要搜索的单词是syllabified,所以部分单词在一行,部分单词在下一行,并且两部分是分开的由连字符和换行符?在这种情况下,解决方案会更加复杂。

标签: c file fgets


【解决方案1】:

那么,我怎样才能读取整个文件

为了将整个文件读入内存缓冲区,您可以使用函数fread。通过附加一个终止空字符将输入转换为字符串后,您可以使用函数strstr 在输入中搜索某个单词。

这是一个执行此操作并在输入中搜索单词targetword的程序:

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

int main( void )
{
    FILE *fp;
    char buffer[1000];
    size_t read;

    //open input file
    fp = fopen( "input.txt", "rt" );
    if ( fp == NULL )
    {
        fprintf( stderr, "ERROR: Unable to open input file!\n" );
        exit( EXIT_FAILURE );
    }

    //read entire file into buffer
    read = fread( buffer, 1, sizeof buffer, fp );

    //verify that buffer was not too small
    if ( read == sizeof buffer )
    {
        fprintf( stderr, "ERROR: Memory buffer is too small to contain entire input!\n" );
        exit( EXIT_FAILURE );
    }

    //add terminating null character to make input a valid
    //null-terminated string
    buffer[read] = '\0';

    //search input for target word
    if ( strstr( buffer, "targetword" ) != NULL )
        printf( "Found word!\n" );
    else
        printf( "Did not find word!\n" );

    fclose( fp );
}

然而,不是一次读取整个文件(这可能需要非常大的内存缓冲区),更常见的是在循环中一次读取一行,并且在每次循环迭代中,检查当前是否行包含您要查找的单词。这样,内存缓冲区只需足够大,即可一次存储一行输入,而不是整个输入。

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

int main( void )
{
    FILE *fp;
    char line[100];
    bool found = false;

    //open input file
    fp = fopen( "input.txt", "rt" );
    if ( fp == NULL )
    {
        fprintf( stderr, "ERROR: Unable to open input file!\n" );
        exit( EXIT_FAILURE );
    }

    //read one line per loop iteration
    while ( fgets( line, sizeof line, fp ) != NULL )
    {
        //verify that line was not too long to fit into buffer
        if ( strchr( line, '\n' ) == NULL )
        {
            fprintf( stderr, "line too long to fit buffer!\n" );
            exit( EXIT_FAILURE );
        }

        //search for target word
        if ( strstr( line, "targetword" ) != NULL )
        {
            found = true;
            break;
        }
    }

    if ( found )
        printf( "Found word!\n" );
    else
        printf( "Did not find word!\n" );

    fclose( fp );
}

但是,这两种解决方案都有几个可能的问题:

  1. 如果目标词targetword 是另一个词的一部分,例如thetargetword,那么它会声明它找到了目标词。我不确定这是否是您想要的,或者您是否希望目标词单独出现。

  2. 如果目标词是syllabified,例如,target-\n 出现在一行中,word 出现在下一行,则程序将无法找到该词。

  3. 搜索是区分大小写的,所以它只会找到targetword,而不是TargetwordTARGETWORD

如有必要,所有这些问题都可以解决,但需要额外的工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-10
    相关资源
    最近更新 更多