鱼C论坛

 找回密码
 立即注册
查看: 2493|回复: 6

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

[复制链接]
发表于 2020-11-6 22:23:22 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

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

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>

  4. char *readLine(FILE *file){
  5.     if(file == NULL){
  6.         exit(1);
  7.     }
  8.     /* malloc linebuffer */
  9.     int baseLen = 256;  // 初始长度设置256字符
  10.     char *lineBuf = (char *)malloc(sizeof(char) * baseLen);
  11.     if(lineBuf == NULL){
  12.         exit(1);
  13.     }

  14.     int ch,index=0;
  15.     while((ch=fgetc(file)) != 10 && ch != EOF){ // ASCII 10 => "\n"
  16.         lineBuf[index] = ch;
  17.         index++;

  18.         if(index == baseLen){
  19.             baseLen += 256;
  20.             lineBuf = (char *)realloc(lineBuf, baseLen); // 内存不足时每次再重新分配256字符空间
  21.             if(lineBuf == NULL){
  22.                 exit(1);
  23.             }
  24.         }
  25.     }
  26.     lineBuf[index] = '\0'; // end of string add '\0'

  27.     return lineBuf;
  28. }

  29. int main(int argc, char *argv[])
  30. {
  31.     FILE *fp = fopen(argv[1],"r");
  32.     if(fp == NULL){
  33.         exit(1);
  34.     }
  35.     while(!feof(fp)){
  36.         char *line = readLine(fp);
  37.         printf("%s\n",line);
  38.     }
  39.     exit(0);
  40. }
复制代码
最佳答案
2020-11-9 13:27:32
大裤衩子 发表于 2020-11-7 20:01
有什么避免输出空串的方法么?
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <unistd.h>

  5. char *readLine(FILE *file) {
  6.     if (file == NULL) {
  7.         exit(1);
  8.     }
  9.     /* malloc linebuffer */
  10.     int baseLen = 256;  // 初始长度设置256字符
  11.     char *lineBuf = (char *) malloc(sizeof(char) * baseLen);
  12.     if (lineBuf == NULL) {
  13.         exit(1);
  14.     }

  15.     int ch, index = 0;

  16.     do {
  17.         ch = fgetc(file);
  18.         lineBuf[index] = ch;
  19.         index++;

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

  28.     lineBuf[index] = '\0'; // end of string add '\0'
  29.     if (EOF == ch) {
  30.         lineBuf[index-1] = '\0';
  31.     }

  32.     return lineBuf;
  33. }

  34. int main(int argc, char *argv[]) {
  35.     FILE *fp = fopen("../main.c", "r");
  36.     if (fp == NULL) {
  37.         exit(1);
  38.     }
  39.     while (!feof(fp)) {
  40.         char *line = readLine(fp);
  41.         printf("%s", line);
  42.     }
  43.     exit(0);
  44. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-11-7 01:32:28 | 显示全部楼层
本帖最后由 jackz007 于 2020-11-7 02:15 编辑

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

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

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

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

  3. int main(int argc , char * argv[])
  4. {
  5.         FILE * fp                                       ;
  6.         char s[2048]                                    ;
  7.         if(argc > 1) {
  8.                 if((fp = fopen(argv[1] , "r")) != NULL) {
  9.                         fgets(s , 2048 , fp)            ;
  10.                         while(! feof(fp)) {
  11.                                 s[strlen(s) - 1] = '\0' ;  /* 去掉字符串末尾的换行符 '\n' */
  12.                                 printf("%s\n" , s)      ;
  13.                                 fgets(s , 2048 , fp)    ;
  14.                         }
  15.                         fclose(fp)                      ;
  16.                 } else {
  17.                         fprintf(stderr , "\n")                          ;
  18.                         fprintf(stderr , "无法打开文件 %s\n" , argv[1]) ;
  19.                         fprintf(stderr , "\n")                          ;
  20.                 }
  21.         } else {
  22.                 fprintf(stderr , "\n")                                  ;
  23.                 fprintf(stderr , "Usage : %s <目标文件>\n" , argv[0])   ;
  24.                 fprintf(stderr , "\n")                                  ;
  25.         }
  26. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

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

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

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-11-7 17:16:56 | 显示全部楼层
最后读到 EOF 时返回了空字符串。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-7 20:01:27 | 显示全部楼层
赚小钱 发表于 2020-11-7 17:16
最后读到 EOF 时返回了空字符串。

有什么避免输出空串的方法么?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-11-9 13:27:32 | 显示全部楼层    本楼为最佳答案   
大裤衩子 发表于 2020-11-7 20:01
有什么避免输出空串的方法么?
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <unistd.h>

  5. char *readLine(FILE *file) {
  6.     if (file == NULL) {
  7.         exit(1);
  8.     }
  9.     /* malloc linebuffer */
  10.     int baseLen = 256;  // 初始长度设置256字符
  11.     char *lineBuf = (char *) malloc(sizeof(char) * baseLen);
  12.     if (lineBuf == NULL) {
  13.         exit(1);
  14.     }

  15.     int ch, index = 0;

  16.     do {
  17.         ch = fgetc(file);
  18.         lineBuf[index] = ch;
  19.         index++;

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

  28.     lineBuf[index] = '\0'; // end of string add '\0'
  29.     if (EOF == ch) {
  30.         lineBuf[index-1] = '\0';
  31.     }

  32.     return lineBuf;
  33. }

  34. int main(int argc, char *argv[]) {
  35.     FILE *fp = fopen("../main.c", "r");
  36.     if (fp == NULL) {
  37.         exit(1);
  38.     }
  39.     while (!feof(fp)) {
  40.         char *line = readLine(fp);
  41.         printf("%s", line);
  42.     }
  43.     exit(0);
  44. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-9 16:34:37 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-9 19:42

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表