C 读取文件到动态列表,动态字符串
C Reading a file to dynamic list, dynamic string
我有一个列表
typedef struct LISTA lista;
struct LISTA
{
char *linia;
int numer;
struct lista *next;
};
Ad 我需要保存一个 .txt 文件,其中的行长度未知。
"linia" 是动态 malloc()
的行,"numer" 是行的编号。
我试图通过一个字符一个字符地阅读它来让它工作,但由于我对 C 的了解有限,我很快就陷入了困境。我在这里找到了几个解决方案,但大多数解决方案都有一个或另一个问题,有些非常复杂,我不明白它做了什么,还有一些在字符串末尾缺少'\0'。
如果有示例并解释它的作用和方式,我将非常高兴。我其实很想学的,不只是完成这个愚蠢的作业
实际任务是用 C 编写一个类似 grep 的程序,但我认为我可以完成其余的机制,但我无法将其全部保存到动态列表中。
查看下面的代码。它将文本文件读取到动态列表,动态字符串。
char * getLineOfAnySize(FILE* fp, size_t typicalSize, 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++] ='[=10=]'; // 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;
}
我有一个列表
typedef struct LISTA lista;
struct LISTA
{
char *linia;
int numer;
struct lista *next;
};
Ad 我需要保存一个 .txt 文件,其中的行长度未知。
"linia" 是动态 malloc()
的行,"numer" 是行的编号。
我试图通过一个字符一个字符地阅读它来让它工作,但由于我对 C 的了解有限,我很快就陷入了困境。我在这里找到了几个解决方案,但大多数解决方案都有一个或另一个问题,有些非常复杂,我不明白它做了什么,还有一些在字符串末尾缺少'\0'。
如果有示例并解释它的作用和方式,我将非常高兴。我其实很想学的,不只是完成这个愚蠢的作业
实际任务是用 C 编写一个类似 grep 的程序,但我认为我可以完成其余的机制,但我无法将其全部保存到动态列表中。
查看下面的代码。它将文本文件读取到动态列表,动态字符串。
char * getLineOfAnySize(FILE* fp, size_t typicalSize, 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++] ='[=10=]'; // 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;
}