C逐行读取文件。

时间:2022-12-03 19:25:32

I wrote this function to read a line from a file:

我编写了这个函数来读取文件中的一行:

const char *readLine(FILE *file) {

    if (file == NULL) {
        printf("Error: file pointer is null.");
        exit(1);
    }

    int maximumLineLength = 128;
    char *lineBuffer = (char *)malloc(sizeof(char) * maximumLineLength);

    if (lineBuffer == NULL) {
        printf("Error allocating memory for line buffer.");
        exit(1);
    }

    char ch = getc(file);
    int count = 0;

    while ((ch != '\n') && (ch != EOF)) {
        if (count == maximumLineLength) {
            maximumLineLength += 128;
            lineBuffer = realloc(lineBuffer, maximumLineLength);
            if (lineBuffer == NULL) {
                printf("Error reallocating space for line buffer.");
                exit(1);
            }
        }
        lineBuffer[count] = ch;
        count++;

        ch = getc(file);
    }

    lineBuffer[count] = '\0';
    char line[count + 1];
    strncpy(line, lineBuffer, (count + 1));
    free(lineBuffer);
    const char *constLine = line;
    return constLine;
}

The function reads the file correctly, and using printf I see that the constLine string did get read correctly as well.

该函数正确读取文件,并且使用printf,我看到constLine字符串也被正确读取。

However, if I use the function e.g. like this:

但是,如果我使用这个函数,例如:

while (!feof(myFile)) {
    const char *line = readLine(myFile);
    printf("%s\n", line);
}

printf outputs gibberish. Why?

printf输出胡言乱语。为什么?

14 个解决方案

#1


212  

If your task is not to invent the line-by-line reading function, but just to read the file line-by-line, you may use a typical code snippet involving the getline() function (see the manual page here):

如果您的任务不是创建逐行读取函数,而是逐行读取文件,那么您可以使用一个包含getline()函数的典型代码片段(参见这里的手册页):

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    FILE * fp;
    char * line = NULL;
    size_t len = 0;
    ssize_t read;

    fp = fopen("/etc/motd", "r");
    if (fp == NULL)
        exit(EXIT_FAILURE);

    while ((read = getline(&line, &len, fp)) != -1) {
        printf("Retrieved line of length %zu :\n", read);
        printf("%s", line);
    }

    fclose(fp);
    if (line)
        free(line);
    exit(EXIT_SUCCESS);
}

#2


16  

In your readLine function, you return a pointer to the line array (Strictly speaking, a pointer to its first character, but the difference is irrelevant here). Since it's an automatic variable (i.e., it's “on the stack”), the memory is reclaimed when the function returns. You see gibberish because printf has put its own stuff on the stack.

在readLine函数中,返回一个指向行数组的指针(严格地说,是指向它的第一个字符的指针,但是这里的区别无关紧要)。因为它是一个自动变量。,它是“在堆栈上”),当函数返回时,内存被回收。你看到了gibberish,因为printf把自己的东西放在堆栈上。

You need to return a dynamically allocated buffer from the function. You already have one, it's lineBuffer; all you have to do is truncate it to the desired length.

您需要从函数返回一个动态分配的缓冲区。你已经有了一个,它是lineBuffer;你所要做的就是将它截断到所需的长度。

    lineBuffer[count] = '\0';
    realloc(lineBuffer, count + 1);
    return lineBuffer;
}

ADDED (response to follow-up question in comment): readLine returns a pointer to the characters that make up the line. This pointer is what you need to work with the contents of the line. It's also what you must pass to free when you've finished using the memory taken by these characters. Here's how you might use the readLine function:

添加(响应后续问题的注释):readLine返回一个指向组成该行的字符的指针。这个指针就是你需要处理的内容。当你完成了这些角色的记忆后,你也必须通过它。下面是如何使用readLine函数:

char *line = readLine(file);
printf("LOG: read a line: %s\n", line);
if (strchr(line, 'a')) { puts("The line contains an a"); }
/* etc. */
free(line);
/* After this point, the memory allocated for the line has been reclaimed.
   You can't use the value of `line` again (though you can assign a new value
   to the `line` variable if you want). */

#3


14  

//open and get the file handle
FILE* fh;
fopen_s(&fh, filename, "r");

//check if file exists
if (fh == NULL){
    printf("file does not exists %s", filename);
    return 0;
}


//read line by line
const size_t line_size = 300;
char* line = malloc(line_size);
while (fgets(line, line_size, fh) != NULL)  {
    printf(line);
}
free(line);    // dont forget to free heap memory

#4


8  

readLine() returns pointer to local variable, which causes undefined behaviour.

readLine()返回指向局部变量的指针,它会导致未定义的行为。

To get around you can:

你可以:

  1. Create variable in caller function and pass its address to readLine()
  2. 在调用方函数中创建变量,并将其地址传递给readLine()
  3. Allocate memory for line using malloc() - in this case line will be persistent
  4. 为使用malloc()的行分配内存,在这种情况下将是持久的。
  5. Use global variable, although it is generally a bad practice
  6. 使用全局变量,尽管这通常是一个糟糕的实践。

#5


7  

FILE* fp;
char buffer[255];

fp = fopen("file.txt", "r");

while(fgets(buffer, 255, (FILE*) fp)) {
    printf("%s\n", buffer);
}

fclose(fp);

#6


4  

Some things wrong with the example:

例子有一些错误:

  • you forgot to add \n to your printfs. Also error messages should go to stderr i.e. fprintf(stderr, ....
  • 您忘记向您的printfs添加\n了。另外,错误消息应该发送到stderr,即fprintf(stderr,)
  • (not a biggy but) consider using fgetc() rather than getc(). getc() is a macro, fgetc() is a proper function
  • 考虑使用fgetc()而不是getc()。getc()是一个宏,fgetc()是一个适当的函数。
  • getc() returns an int so ch should be declared as an int. This is important since the comparison with EOF will be handled correctly. Some 8 bit character sets use 0xFF as a valid character (ISO-LATIN-1 would be an example) and EOF which is -1, will be 0xFF if assigned to a char.
  • getc()返回一个int,所以ch应该被声明为int。这很重要,因为与EOF的比较将被正确处理。一些8位字符集使用0xFF作为一个有效字符(ISO-LATIN-1是一个例子),EOF是-1,如果分配给一个char,那么它将是0xFF。
  • There is a potential buffer overflow at the line

    这一行有一个潜在的缓冲区溢出。

    lineBuffer[count] = '\0';
    

    If the line is exactly 128 characters long, count is 128 at the point that gets executed.

    如果该行的长度恰好是128个字符,那么在执行时,count是128。

  • As others have pointed out, line is a locally declared array. You can't return a pointer to it.

    正如其他人指出的,line是一个本地声明的数组。你不能返回一个指向它的指针。

  • strncpy(count + 1) will copy at most count + 1 characters but will terminate if it hits '\0' Because you set lineBuffer[count] to '\0' you know it will never get to count + 1. However, if it did, it would not put a terminating '\0' on, so you need to do it. You often see something like the following:

    strncpy(count + 1)将在大多数count + 1字符中复制,但如果它命中“\0”,则会终止,因为您将lineBuffer[count]设置为“\0”,您知道它将永远无法计数+ 1。但是,如果它做到了,它就不会终止“\0”,所以您需要这样做。你经常会看到如下内容:

    char buffer [BUFFER_SIZE];
    strncpy(buffer, sourceString, BUFFER_SIZE - 1);
    buffer[BUFFER_SIZE - 1] = '\0';
    
  • if you malloc() a line to return (in place of your local char array), your return type should be char* - drop the const.

    如果您malloc()一行返回(替代了本地char数组),则返回类型应该是char* - drop const。

#7


4  

Use fgets() to read a line from a file handle.

使用fgets()从文件句柄读取一行。

#8


2  

void readLine(FILE* file, char* line, int limit)
{
    int i;
    int read;

    read = fread(line, sizeof(char), limit, file);
    line[read] = '\0';

    for(i = 0; i <= read;i++)
    {
        if('\0' == line[i] || '\n' == line[i] || '\r' == line[i])
        {
            line[i] = '\0';
            break;
        }
    }

    if(i != read)
    {
        fseek(file, i - read + 1, SEEK_CUR);
    }
}

what about this one?

这一个怎么样?

#9


2  

Here is my several hours... Reading whole file line by line.

这是我的几个小时…逐行读取整个文件。

char * readline(FILE *fp, char *buffer)
{
    int ch;
    int i = 0;
    size_t buff_len = 0;

    buffer = malloc(buff_len + 1);
    if (!buffer) return NULL;  // Out of memory

    while ((ch = fgetc(fp)) != '\n' && ch != EOF)
    {
        buff_len++;
        void *tmp = realloc(buffer, buff_len + 1);
        if (tmp == NULL)
        {
            free(buffer);
            return NULL; // Out of memory
        }
        buffer = tmp;

        buffer[i] = (char) ch;
        i++;
    }
    buffer[i] = '\0';

    // Detect end
    if (ch == EOF && (i == 0 || ferror(fp)))
    {
        free(buffer);
        return NULL;
    }
    return buffer;
}

void lineByline(FILE * file){
char *s;
while ((s = readline(file, 0)) != NULL)
{
    puts(s);
    free(s);
    printf("\n");
}
}

int main()
{
    char *fileName = "input-1.txt";
    FILE* file = fopen(fileName, "r");
    lineByline(file);
    return 0;
}

#10


1  

You should use the ANSI functions for reading a line, eg. fgets. After calling you need free() in calling context, eg:

你应该使用ANSI函数来读取一行。fgets。在打电话给你之后,你需要免费()。

...
const char *entirecontent=readLine(myFile);
puts(entirecontent);
free(entirecontent);
...

const char *readLine(FILE *file)
{
  char *lineBuffer=calloc(1,1), line[128];

  if ( !file || !lineBuffer )
  {
    fprintf(stderr,"an ErrorNo 1: ...");
    exit(1);
  }

  for(; fgets(line,sizeof line,file) ; strcat(lineBuffer,line) )
  {
    if( strchr(line,'\n') ) *strchr(line,'\n')=0;
    lineBuffer=realloc(lineBuffer,strlen(lineBuffer)+strlen(line)+1);
    if( !lineBuffer )
    {
      fprintf(stderr,"an ErrorNo 2: ...");
      exit(2);
    }
  }
  return lineBuffer;
}

#11


0  

const char *readLine(FILE *file, char* line) {

    if (file == NULL) {
        printf("Error: file pointer is null.");
        exit(1);
    }

    int maximumLineLength = 128;
    char *lineBuffer = (char *)malloc(sizeof(char) * maximumLineLength);

    if (lineBuffer == NULL) {
        printf("Error allocating memory for line buffer.");
        exit(1);
    }

    char ch = getc(file);
    int count = 0;

    while ((ch != '\n') && (ch != EOF)) {
        if (count == maximumLineLength) {
            maximumLineLength += 128;
            lineBuffer = realloc(lineBuffer, maximumLineLength);
            if (lineBuffer == NULL) {
                printf("Error reallocating space for line buffer.");
                exit(1);
            }
        }
        lineBuffer[count] = ch;
        count++;

        ch = getc(file);
    }

    lineBuffer[count] = '\0';
    char line[count + 1];
    strncpy(line, lineBuffer, (count + 1));
    free(lineBuffer);
    return line;

}


char linebuffer[256];
while (!feof(myFile)) {
    const char *line = readLine(myFile, linebuffer);
    printf("%s\n", line);
}

note that the 'line' variable is declared in calling function and then passed, so your readLine function fills predefined buffer and just returns it. This is the way most of C libraries work.

注意,“line”变量在调用函数中声明,然后通过,所以您的readLine函数将填充预定义的缓冲区,并返回它。这是大多数C库的工作方式。

There are other ways, which I'm aware of:

还有其他的方法,我知道

  • defining the char line[] as static (static char line[MAX_LINE_LENGTH] -> it will hold it's value AFTER returning from the function). -> bad, the function is not reentrant, and race condition can occur -> if you call it twice from two threads, it will overwrite it's results
  • 定义char line[]为静态的(静态char line[MAX_LINE_LENGTH] ->,从函数返回后它将保留它的值)。->不好,函数不可重入,竞态条件可以发生->如果你从两个线程调用它两次,它会覆盖结果。
  • malloc()ing the char line[], and freeing it in calling functions -> too many expensive mallocs, and, delegating the responsibility to free the buffer to another function (the most elegant solution is to call malloc and free on any buffers in same function)
  • malloc()处理char[],并将其释放到调用函数中——>太多昂贵的mallocs,并将缓冲区释放到另一个函数(最优雅的解决方案是调用malloc,并在相同函数的任何缓冲区中释放)

btw, 'explicit' casting from char* to const char* is redundant.

btw,从char*到const char*的“显式”转换是多余的。

btw2, there is no need to malloc() the lineBuffer, just define it char lineBuffer[128], so you don't need to free it

btw2,不需要malloc()的lineBuffer,只是定义它char lineBuffer[128],所以您不需要释放它。

btw3 do not use 'dynamic sized stack arrays' (defining the array as char arrayName[some_nonconstant_variable]), if you don't exactly know what are you doing, it works only in C99.

btw3不使用“动态大小的堆栈数组”(将数组定义为char arrayName[some_nonconstant_variable]),如果您不确切知道您在做什么,它只在C99中工作。

#12


0  

You make the mistake of returning a pointer to an automatic variable. The variable line is allocated in the stack and only lives as long as the function lives. You are not allowed to return a pointer to it, because as soon as it returns the memory will be given elsewhere.

您犯的错误是返回一个指向自动变量的指针。变量行是在堆栈中分配的,只有在函数使用时才会存在。您不允许返回一个指向它的指针,因为一旦它返回内存,将会在其他地方给出。

const char* func x(){
    char line[100];
    return (const char*) line; //illegal
}

To avoid this, you either return a pointer to memory which resides on the heap eg. lineBuffer and it should be the user's responsibility to call free() when he is done with it. Alternatively you can ask the user to pass you as an argument a memory address on which to write the line contents at.

为了避免这种情况,您可以返回一个指向堆上的内存的指针。lineBuffer和它应该是用户在完成它时调用free()的责任。或者,您可以要求用户将您作为一个参数传递给您,以便在其中写入行内容。

#13


0  

I want a code from ground 0 so i did this to read the content of dictionary's word line by line.

我想要一个来自于ground 0的代码,所以我这样做是为了逐行读取字典单词的内容。

char temp_str[20]; // you can change the buffer size according to your requirements And A single line's length in a File.

char temp_str[20];//您可以根据您的需求和文件中的单行长度来更改缓冲区的大小。

Note I've initialized the buffer With Null character each time I read line.This function can be Automated But Since I need A proof of Concept and want to design a programme Byte By Byte

注意,每次读行时,我都用Null字符初始化缓冲区。这个函数可以是自动的,但是因为我需要一个概念证明,并且想要按字节设计一个程序字节。

#include<stdio.h>

int main()
{
int i;
char temp_ch;
FILE *fp=fopen("data.txt","r");
while(temp_ch!=EOF)
{
 i=0;
  char temp_str[20]={'\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'};
while(temp_ch!='\n')
{
  temp_ch=fgetc(fp);
  temp_str[i]=temp_ch;
  i++;
}
if(temp_ch=='\n')
{
temp_ch=fgetc(fp);
temp_str[i]=temp_ch;
}
printf("%s",temp_str);
}
return 0;
}

#14


0  

Implement method to read, and get content from a file (input1.txt)

实现读取的方法,并从文件中获取内容(input1.txt)

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

void testGetFile() {
    // open file
    FILE *fp = fopen("input1.txt", "r");
    size_t len = 255;
    // need malloc memory for line, if not, segmentation fault error will occurred.
    char *line = malloc(sizeof(char) * len);
    // check if file exist (and you can open it) or not
    if (fp == NULL) {
        printf("can open file input1.txt!");
        return;
    }
    while(fgets(line, len, fp) != NULL) {
        printf("%s\n", line);
    }
    free(line);
}

Hope this help. Happy coding!

希望这个有帮助。编码快乐!

#1


212  

If your task is not to invent the line-by-line reading function, but just to read the file line-by-line, you may use a typical code snippet involving the getline() function (see the manual page here):

如果您的任务不是创建逐行读取函数,而是逐行读取文件,那么您可以使用一个包含getline()函数的典型代码片段(参见这里的手册页):

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    FILE * fp;
    char * line = NULL;
    size_t len = 0;
    ssize_t read;

    fp = fopen("/etc/motd", "r");
    if (fp == NULL)
        exit(EXIT_FAILURE);

    while ((read = getline(&line, &len, fp)) != -1) {
        printf("Retrieved line of length %zu :\n", read);
        printf("%s", line);
    }

    fclose(fp);
    if (line)
        free(line);
    exit(EXIT_SUCCESS);
}

#2


16  

In your readLine function, you return a pointer to the line array (Strictly speaking, a pointer to its first character, but the difference is irrelevant here). Since it's an automatic variable (i.e., it's “on the stack”), the memory is reclaimed when the function returns. You see gibberish because printf has put its own stuff on the stack.

在readLine函数中,返回一个指向行数组的指针(严格地说,是指向它的第一个字符的指针,但是这里的区别无关紧要)。因为它是一个自动变量。,它是“在堆栈上”),当函数返回时,内存被回收。你看到了gibberish,因为printf把自己的东西放在堆栈上。

You need to return a dynamically allocated buffer from the function. You already have one, it's lineBuffer; all you have to do is truncate it to the desired length.

您需要从函数返回一个动态分配的缓冲区。你已经有了一个,它是lineBuffer;你所要做的就是将它截断到所需的长度。

    lineBuffer[count] = '\0';
    realloc(lineBuffer, count + 1);
    return lineBuffer;
}

ADDED (response to follow-up question in comment): readLine returns a pointer to the characters that make up the line. This pointer is what you need to work with the contents of the line. It's also what you must pass to free when you've finished using the memory taken by these characters. Here's how you might use the readLine function:

添加(响应后续问题的注释):readLine返回一个指向组成该行的字符的指针。这个指针就是你需要处理的内容。当你完成了这些角色的记忆后,你也必须通过它。下面是如何使用readLine函数:

char *line = readLine(file);
printf("LOG: read a line: %s\n", line);
if (strchr(line, 'a')) { puts("The line contains an a"); }
/* etc. */
free(line);
/* After this point, the memory allocated for the line has been reclaimed.
   You can't use the value of `line` again (though you can assign a new value
   to the `line` variable if you want). */

#3


14  

//open and get the file handle
FILE* fh;
fopen_s(&fh, filename, "r");

//check if file exists
if (fh == NULL){
    printf("file does not exists %s", filename);
    return 0;
}


//read line by line
const size_t line_size = 300;
char* line = malloc(line_size);
while (fgets(line, line_size, fh) != NULL)  {
    printf(line);
}
free(line);    // dont forget to free heap memory

#4


8  

readLine() returns pointer to local variable, which causes undefined behaviour.

readLine()返回指向局部变量的指针,它会导致未定义的行为。

To get around you can:

你可以:

  1. Create variable in caller function and pass its address to readLine()
  2. 在调用方函数中创建变量,并将其地址传递给readLine()
  3. Allocate memory for line using malloc() - in this case line will be persistent
  4. 为使用malloc()的行分配内存,在这种情况下将是持久的。
  5. Use global variable, although it is generally a bad practice
  6. 使用全局变量,尽管这通常是一个糟糕的实践。

#5


7  

FILE* fp;
char buffer[255];

fp = fopen("file.txt", "r");

while(fgets(buffer, 255, (FILE*) fp)) {
    printf("%s\n", buffer);
}

fclose(fp);

#6


4  

Some things wrong with the example:

例子有一些错误:

  • you forgot to add \n to your printfs. Also error messages should go to stderr i.e. fprintf(stderr, ....
  • 您忘记向您的printfs添加\n了。另外,错误消息应该发送到stderr,即fprintf(stderr,)
  • (not a biggy but) consider using fgetc() rather than getc(). getc() is a macro, fgetc() is a proper function
  • 考虑使用fgetc()而不是getc()。getc()是一个宏,fgetc()是一个适当的函数。
  • getc() returns an int so ch should be declared as an int. This is important since the comparison with EOF will be handled correctly. Some 8 bit character sets use 0xFF as a valid character (ISO-LATIN-1 would be an example) and EOF which is -1, will be 0xFF if assigned to a char.
  • getc()返回一个int,所以ch应该被声明为int。这很重要,因为与EOF的比较将被正确处理。一些8位字符集使用0xFF作为一个有效字符(ISO-LATIN-1是一个例子),EOF是-1,如果分配给一个char,那么它将是0xFF。
  • There is a potential buffer overflow at the line

    这一行有一个潜在的缓冲区溢出。

    lineBuffer[count] = '\0';
    

    If the line is exactly 128 characters long, count is 128 at the point that gets executed.

    如果该行的长度恰好是128个字符,那么在执行时,count是128。

  • As others have pointed out, line is a locally declared array. You can't return a pointer to it.

    正如其他人指出的,line是一个本地声明的数组。你不能返回一个指向它的指针。

  • strncpy(count + 1) will copy at most count + 1 characters but will terminate if it hits '\0' Because you set lineBuffer[count] to '\0' you know it will never get to count + 1. However, if it did, it would not put a terminating '\0' on, so you need to do it. You often see something like the following:

    strncpy(count + 1)将在大多数count + 1字符中复制,但如果它命中“\0”,则会终止,因为您将lineBuffer[count]设置为“\0”,您知道它将永远无法计数+ 1。但是,如果它做到了,它就不会终止“\0”,所以您需要这样做。你经常会看到如下内容:

    char buffer [BUFFER_SIZE];
    strncpy(buffer, sourceString, BUFFER_SIZE - 1);
    buffer[BUFFER_SIZE - 1] = '\0';
    
  • if you malloc() a line to return (in place of your local char array), your return type should be char* - drop the const.

    如果您malloc()一行返回(替代了本地char数组),则返回类型应该是char* - drop const。

#7


4  

Use fgets() to read a line from a file handle.

使用fgets()从文件句柄读取一行。

#8


2  

void readLine(FILE* file, char* line, int limit)
{
    int i;
    int read;

    read = fread(line, sizeof(char), limit, file);
    line[read] = '\0';

    for(i = 0; i <= read;i++)
    {
        if('\0' == line[i] || '\n' == line[i] || '\r' == line[i])
        {
            line[i] = '\0';
            break;
        }
    }

    if(i != read)
    {
        fseek(file, i - read + 1, SEEK_CUR);
    }
}

what about this one?

这一个怎么样?

#9


2  

Here is my several hours... Reading whole file line by line.

这是我的几个小时…逐行读取整个文件。

char * readline(FILE *fp, char *buffer)
{
    int ch;
    int i = 0;
    size_t buff_len = 0;

    buffer = malloc(buff_len + 1);
    if (!buffer) return NULL;  // Out of memory

    while ((ch = fgetc(fp)) != '\n' && ch != EOF)
    {
        buff_len++;
        void *tmp = realloc(buffer, buff_len + 1);
        if (tmp == NULL)
        {
            free(buffer);
            return NULL; // Out of memory
        }
        buffer = tmp;

        buffer[i] = (char) ch;
        i++;
    }
    buffer[i] = '\0';

    // Detect end
    if (ch == EOF && (i == 0 || ferror(fp)))
    {
        free(buffer);
        return NULL;
    }
    return buffer;
}

void lineByline(FILE * file){
char *s;
while ((s = readline(file, 0)) != NULL)
{
    puts(s);
    free(s);
    printf("\n");
}
}

int main()
{
    char *fileName = "input-1.txt";
    FILE* file = fopen(fileName, "r");
    lineByline(file);
    return 0;
}

#10


1  

You should use the ANSI functions for reading a line, eg. fgets. After calling you need free() in calling context, eg:

你应该使用ANSI函数来读取一行。fgets。在打电话给你之后,你需要免费()。

...
const char *entirecontent=readLine(myFile);
puts(entirecontent);
free(entirecontent);
...

const char *readLine(FILE *file)
{
  char *lineBuffer=calloc(1,1), line[128];

  if ( !file || !lineBuffer )
  {
    fprintf(stderr,"an ErrorNo 1: ...");
    exit(1);
  }

  for(; fgets(line,sizeof line,file) ; strcat(lineBuffer,line) )
  {
    if( strchr(line,'\n') ) *strchr(line,'\n')=0;
    lineBuffer=realloc(lineBuffer,strlen(lineBuffer)+strlen(line)+1);
    if( !lineBuffer )
    {
      fprintf(stderr,"an ErrorNo 2: ...");
      exit(2);
    }
  }
  return lineBuffer;
}

#11


0  

const char *readLine(FILE *file, char* line) {

    if (file == NULL) {
        printf("Error: file pointer is null.");
        exit(1);
    }

    int maximumLineLength = 128;
    char *lineBuffer = (char *)malloc(sizeof(char) * maximumLineLength);

    if (lineBuffer == NULL) {
        printf("Error allocating memory for line buffer.");
        exit(1);
    }

    char ch = getc(file);
    int count = 0;

    while ((ch != '\n') && (ch != EOF)) {
        if (count == maximumLineLength) {
            maximumLineLength += 128;
            lineBuffer = realloc(lineBuffer, maximumLineLength);
            if (lineBuffer == NULL) {
                printf("Error reallocating space for line buffer.");
                exit(1);
            }
        }
        lineBuffer[count] = ch;
        count++;

        ch = getc(file);
    }

    lineBuffer[count] = '\0';
    char line[count + 1];
    strncpy(line, lineBuffer, (count + 1));
    free(lineBuffer);
    return line;

}


char linebuffer[256];
while (!feof(myFile)) {
    const char *line = readLine(myFile, linebuffer);
    printf("%s\n", line);
}

note that the 'line' variable is declared in calling function and then passed, so your readLine function fills predefined buffer and just returns it. This is the way most of C libraries work.

注意,“line”变量在调用函数中声明,然后通过,所以您的readLine函数将填充预定义的缓冲区,并返回它。这是大多数C库的工作方式。

There are other ways, which I'm aware of:

还有其他的方法,我知道

  • defining the char line[] as static (static char line[MAX_LINE_LENGTH] -> it will hold it's value AFTER returning from the function). -> bad, the function is not reentrant, and race condition can occur -> if you call it twice from two threads, it will overwrite it's results
  • 定义char line[]为静态的(静态char line[MAX_LINE_LENGTH] ->,从函数返回后它将保留它的值)。->不好,函数不可重入,竞态条件可以发生->如果你从两个线程调用它两次,它会覆盖结果。
  • malloc()ing the char line[], and freeing it in calling functions -> too many expensive mallocs, and, delegating the responsibility to free the buffer to another function (the most elegant solution is to call malloc and free on any buffers in same function)
  • malloc()处理char[],并将其释放到调用函数中——>太多昂贵的mallocs,并将缓冲区释放到另一个函数(最优雅的解决方案是调用malloc,并在相同函数的任何缓冲区中释放)

btw, 'explicit' casting from char* to const char* is redundant.

btw,从char*到const char*的“显式”转换是多余的。

btw2, there is no need to malloc() the lineBuffer, just define it char lineBuffer[128], so you don't need to free it

btw2,不需要malloc()的lineBuffer,只是定义它char lineBuffer[128],所以您不需要释放它。

btw3 do not use 'dynamic sized stack arrays' (defining the array as char arrayName[some_nonconstant_variable]), if you don't exactly know what are you doing, it works only in C99.

btw3不使用“动态大小的堆栈数组”(将数组定义为char arrayName[some_nonconstant_variable]),如果您不确切知道您在做什么,它只在C99中工作。

#12


0  

You make the mistake of returning a pointer to an automatic variable. The variable line is allocated in the stack and only lives as long as the function lives. You are not allowed to return a pointer to it, because as soon as it returns the memory will be given elsewhere.

您犯的错误是返回一个指向自动变量的指针。变量行是在堆栈中分配的,只有在函数使用时才会存在。您不允许返回一个指向它的指针,因为一旦它返回内存,将会在其他地方给出。

const char* func x(){
    char line[100];
    return (const char*) line; //illegal
}

To avoid this, you either return a pointer to memory which resides on the heap eg. lineBuffer and it should be the user's responsibility to call free() when he is done with it. Alternatively you can ask the user to pass you as an argument a memory address on which to write the line contents at.

为了避免这种情况,您可以返回一个指向堆上的内存的指针。lineBuffer和它应该是用户在完成它时调用free()的责任。或者,您可以要求用户将您作为一个参数传递给您,以便在其中写入行内容。

#13


0  

I want a code from ground 0 so i did this to read the content of dictionary's word line by line.

我想要一个来自于ground 0的代码,所以我这样做是为了逐行读取字典单词的内容。

char temp_str[20]; // you can change the buffer size according to your requirements And A single line's length in a File.

char temp_str[20];//您可以根据您的需求和文件中的单行长度来更改缓冲区的大小。

Note I've initialized the buffer With Null character each time I read line.This function can be Automated But Since I need A proof of Concept and want to design a programme Byte By Byte

注意,每次读行时,我都用Null字符初始化缓冲区。这个函数可以是自动的,但是因为我需要一个概念证明,并且想要按字节设计一个程序字节。

#include<stdio.h>

int main()
{
int i;
char temp_ch;
FILE *fp=fopen("data.txt","r");
while(temp_ch!=EOF)
{
 i=0;
  char temp_str[20]={'\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'};
while(temp_ch!='\n')
{
  temp_ch=fgetc(fp);
  temp_str[i]=temp_ch;
  i++;
}
if(temp_ch=='\n')
{
temp_ch=fgetc(fp);
temp_str[i]=temp_ch;
}
printf("%s",temp_str);
}
return 0;
}

#14


0  

Implement method to read, and get content from a file (input1.txt)

实现读取的方法,并从文件中获取内容(input1.txt)

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

void testGetFile() {
    // open file
    FILE *fp = fopen("input1.txt", "r");
    size_t len = 255;
    // need malloc memory for line, if not, segmentation fault error will occurred.
    char *line = malloc(sizeof(char) * len);
    // check if file exist (and you can open it) or not
    if (fp == NULL) {
        printf("can open file input1.txt!");
        return;
    }
    while(fgets(line, len, fp) != NULL) {
        printf("%s\n", line);
    }
    free(line);
}

Hope this help. Happy coding!

希望这个有帮助。编码快乐!