C 读取文件到动态列表、动态字符串

标签 c string file dynamic-list

我有一个 list

typedef struct LISTA lista;
struct LISTA
{
    char *linia;
    int numer;
    struct lista *next;
};

我需要获取一个保存到其中的行长度未知的 .txt 文件。 “linia”是动态 malloc() 编辑的行,“numer”是行的编号。

我试图通过逐个字符地阅读它来让它工作,但由于我对 C 的了解有限,我很快就陷入了困境。我在这里找到了几种解决方案,但大多数都有这样或那样的问题,有些非常复杂,我无法理解它的作用,还有一些在字符串末尾缺少“\0”。

我真的很高兴能有一个例子并解释它的作用和方式。我其实想学它,而不仅仅是完成这个愚蠢的作业

实际的任务是用 C 语言编写一个类似 grep 的程序,但我认为我可以完成其余的机制,但我很难将其全部保存到动态列表中。

最佳答案

请参阅下面的代码。它将文本文件读取到动态列表、动态字符串中。 char * getLineOfAnySize(FILE* fp, size_t genericSize, int *endOfLineDetected); 在这里至关重要。

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

struct list
{
    char *linia;
    int numer;
    struct list *next;
};

typedef struct list LIST;

char * getLineOfAnySize(FILE* fp, size_t typicalSize, int *endOfLineDetected,size_t *nrOfCharRead){ 
    char *line;       // buffer for our string
    int ch;           // we will read line character by character
    size_t len = 0;   // number of characters read (character counter)
    size_t lineSize = typicalSize;  // initial size of the buffer allocated for the line
    *nrOfCharRead = 0;

    if(!fp) return NULL; // protection

    // allocating the buffer
    line = realloc(NULL, sizeof(char)*lineSize); // expected size of the line is up to typicalSize

    if (!line) return line; // protection, if we fail to allocate the memory we will return NULL

    while (1) { // loop forever     
        ch = fgetc(fp);       // getting character by character from file

        if (ch == '\n') break; // end of line detected - breaking the loop 
        if( ch == EOF)  {
            *endOfLineDetected = 1;
            break; // end of file detected - breaking the loop
         }

        line[len++] = ch;     // store the character in the line buffer, increase character counter

        if (len == lineSize){ // we reached the end of line buffer (no more room)

        lineSize = lineSize + 64; // we have to increase the line size 
        line = realloc(line, sizeof(char)*(lineSize)); // line buffer has new size now

        if (!line) return line; // if we fail to allocate memory we will return NULL
        }
    }

    if( (len == 0) && *endOfLineDetected) return NULL; // empty file

    line[len++] ='\0';  // ending the string (notice there is no '\n' in the string)
    *nrOfCharRead = len;

    return line;       // return the string
}

int main(void) 
{
    FILE *fp = NULL;   // file handle
    char *line; // 
    int endOfLineDetected = 0;
    size_t nrOfCharRead = 0;

    LIST *current, *head; // pointers to list elements

    head = current = NULL; // init to NULL

    fp = fopen("document.txt", "r"); // open file for reading
    int nr = 0;

    while( line = getLineOfAnySize(fp,128,&endOfLineDetected,&nrOfCharRead) ){ // read the file

         if( (nrOfCharRead == 0) && endOfLineDetected) break;             

        // create new list element 

        LIST *node = malloc (sizeof(LIST));

        nr = nr + 1;  
        node->linia = line;   // initialize the linia
        node->numer = nr;     // update the line number

        node->next = NULL; // next element do not exist yet

        if(head == NULL)
        {
            current = head = node;
        } else 
        {
            current = current->next = node;
        }

        if (endOfLineDetected) break;
    }

    if (fp) fclose(fp); // remember to close the file

    //print, go via all elements of the list till you get NULL next element
    for(current = head; current ; current=current->next){
        printf("line nr=%d line= %s",current->numer, current->linia );
    }
    return 0;
}

关于C 读取文件到动态列表、动态字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37768864/

相关文章:

c# - 在C#中更改图像路径的文件名

java - 用 Java 高效地解析和写入文件

string - 如何找到字典序最小的字符串旋转数?

android - 创建的文件夹在文件资源管理器中不可见。

c++ - 目前在 Ubuntu C/C++ 中如何将 IANA 时区名称转换为 UTC 偏移量

c - 查找数字上最大值的位置

c - 二结构一功能

输出字符的 C 程序会生成整数

c - 文件写入; SSH_AGENT_PID=2547?

java - 为什么 Apache Camel 文件到 sftp 路由失败