大裤衩子 发表于 2020-11-6 22:23:22

从文件中读取整行,输出最后会多出一个空行问题

问题如题,遍历文件后输出,不明白多出来的空行怎么出现的。

PS:内存申请了没有释放这个题暂且不论。

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

char *readLine(FILE *file){
    if(file == NULL){
      exit(1);
    }
    /* malloc linebuffer */
    int baseLen = 256;// 初始长度设置256字符
    char *lineBuf = (char *)malloc(sizeof(char) * baseLen);
    if(lineBuf == NULL){
      exit(1);
    }

    int ch,index=0;
    while((ch=fgetc(file)) != 10 && ch != EOF){ // ASCII 10 => "\n"
      lineBuf = ch;
      index++;

      if(index == baseLen){
            baseLen += 256;
            lineBuf = (char *)realloc(lineBuf, baseLen); // 内存不足时每次再重新分配256字符空间
            if(lineBuf == NULL){
                exit(1);
            }
      }
    }
    lineBuf = '\0'; // end of string add '\0'

    return lineBuf;
}

int main(int argc, char *argv[])
{
    FILE *fp = fopen(argv,"r");
    if(fp == NULL){
      exit(1);
    }
    while(!feof(fp)){
      char *line = readLine(fp);
      printf("%s\n",line);
    }
    exit(0);
}

jackz007 发表于 2020-11-7 01:32:28

本帖最后由 jackz007 于 2020-11-7 02:15 编辑

      很简单,每行文本的末尾本身都是自带换行符的。显示的时候再加一个换行符,于是,就空出一行来了。我想问楼主 2 个问题:

1、为何一定要动态开辟字符串存储空间,申请足够大的固定空间不简单吗?

2、整行读取文本文件为何不用 fgets() 函数,这个函数可以每次读取文件一整行的内容,用起来岂不更加简单方便?

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

int main(int argc , char * argv[])
{
      FILE * fp                                       ;
      char s                                    ;
      if(argc > 1) {
                if((fp = fopen(argv , "r")) != NULL) {
                        fgets(s , 2048 , fp)            ;
                        while(! feof(fp)) {
                              s = '\0' ;/* 去掉字符串末尾的换行符 '\n' */
                              printf("%s\n" , s)      ;
                              fgets(s , 2048 , fp)    ;
                        }
                        fclose(fp)                      ;
                } else {
                        fprintf(stderr , "\n")                        ;
                        fprintf(stderr , "无法打开文件 %s\n" , argv) ;
                        fprintf(stderr , "\n")                        ;
                }
      } else {
                fprintf(stderr , "\n")                                  ;
                fprintf(stderr , "Usage : %s <目标文件>\n" , argv)   ;
                fprintf(stderr , "\n")                                  ;
      }
}

大裤衩子 发表于 2020-11-7 09:49:57

jackz007 发表于 2020-11-7 01:32
很简单,每行文本的末尾本身都是自带换行符的。显示的时候再加一个换行符,于是,就空出一行来了。我 ...

你的回答不对,我的函数里在第17行处:ch=fgetc(file)) != 10 已经去掉了换行符"\n", 按照你的说法本身带有空行,那么输出的时候就是每间隔一个空行一个输出,而不是最后一行有空行{:10_256:}。

我再回答你的问题:申请足够大的固定空间简单,但不满足我的需求,我要读入的文件每行长度不一致,这也是我不用fgets的原因{:10_327:}。

没有回答我的问题,还是谢谢啦!

赚小钱 发表于 2020-11-7 17:16:56

最后读到 EOF 时返回了空字符串。

大裤衩子 发表于 2020-11-7 20:01:27

赚小钱 发表于 2020-11-7 17:16
最后读到 EOF 时返回了空字符串。

有什么避免输出空串的方法么?

赚小钱 发表于 2020-11-9 13:27:32

大裤衩子 发表于 2020-11-7 20:01
有什么避免输出空串的方法么?

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

char *readLine(FILE *file) {
    if (file == NULL) {
      exit(1);
    }
    /* malloc linebuffer */
    int baseLen = 256;// 初始长度设置256字符
    char *lineBuf = (char *) malloc(sizeof(char) * baseLen);
    if (lineBuf == NULL) {
      exit(1);
    }

    int ch, index = 0;

    do {
      ch = fgetc(file);
      lineBuf = ch;
      index++;

      if (index == baseLen) {
            baseLen += 256;
            lineBuf = (char *) realloc(lineBuf, baseLen); // 内存不足时每次再重新分配256字符空间
            if (lineBuf == NULL) {
                exit(1);
            }
      }
    } while (ch != 10 && ch != EOF);

    lineBuf = '\0'; // end of string add '\0'
    if (EOF == ch) {
      lineBuf = '\0';
    }

    return lineBuf;
}

int main(int argc, char *argv[]) {
    FILE *fp = fopen("../main.c", "r");
    if (fp == NULL) {
      exit(1);
    }
    while (!feof(fp)) {
      char *line = readLine(fp);
      printf("%s", line);
    }
    exit(0);
}

大裤衩子 发表于 2020-11-9 16:34:37

赚小钱 发表于 2020-11-9 13:27


页: [1]
查看完整版本: 从文件中读取整行,输出最后会多出一个空行问题