鱼C论坛

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

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

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

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

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

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

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[index] = ch;
        index++;

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

    return lineBuf;
}

int main(int argc, char *argv[])
{
    FILE *fp = fopen(argv[1],"r");
    if(fp == NULL){
        exit(1);
    }
    while(!feof(fp)){
        char *line = readLine(fp);
        printf("%s\n",line);
    }
    exit(0);
}
最佳答案
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[index] = ch;
        index++;

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

    lineBuf[index] = '\0'; // end of string add '\0'
    if (EOF == ch) {
        lineBuf[index-1] = '\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);
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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[2048]                                    ;
        if(argc > 1) {
                if((fp = fopen(argv[1] , "r")) != NULL) {
                        fgets(s , 2048 , fp)            ;
                        while(! feof(fp)) {
                                s[strlen(s) - 1] = '\0' ;  /* 去掉字符串末尾的换行符 '\n' */ 
                                printf("%s\n" , s)      ;
                                fgets(s , 2048 , fp)    ;
                        }
                        fclose(fp)                      ;
                } else {
                        fprintf(stderr , "\n")                          ;
                        fprintf(stderr , "无法打开文件 %s\n" , argv[1]) ;
                        fprintf(stderr , "\n")                          ;
                }
        } else {
                fprintf(stderr , "\n")                                  ;
                fprintf(stderr , "Usage : %s <目标文件>\n" , argv[0])   ;
                fprintf(stderr , "\n")                                  ;
        }
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

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

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

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-11-7 17:16:56 | 显示全部楼层
最后读到 EOF 时返回了空字符串。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

有什么避免输出空串的方法么?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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[index] = ch;
        index++;

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

    lineBuf[index] = '\0'; // end of string add '\0'
    if (EOF == ch) {
        lineBuf[index-1] = '\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);
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-9 16:34:37 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-12 17:21

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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