【问题标题】:Reading Strings of unknown length from text file and printing them从文本文件中读取长度未知的字符串并打印出来
【发布时间】:2014-07-21 07:56:57
【问题描述】:

我有一个问题,当程序遇到“\n”时,如何从文本文件中读取长度未知的字符串并打印出来。如果程序注意到文件没有更多的字符串可供读取,程序应该结束。

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

#define DEFLEN 2 
#define CHUNKSZ 2 


char *getStrFromFile(FILE *fpin); 

int main(void)
{
      FILE *fpin;
      fpin = fopen("test.txt","r");
      int d = 0;

while(1)
{
    char *ln;
    ln = getStrFromFile(fpin);
    if (!ln)
        break;
    ++d;
    printf("line %d : %s\n", d, ln);
    free(ln);
}
    fclose(fpin);
    return(0);
}



char *getStrFromFile(FILE *fpin) 
{

    int i = 0;
    char *line;


    line = (char*)malloc(DEFLEN);

    fgets(line,strlen(line),fpin);

        if(line[strlen(line-1)] == '\n')

            return line;

char  *temp;
temp = line;
char *read;

    read = (char*)malloc(CHUNKSZ);

    fgets(read,strlen(read),fpin);

    line = (char*)malloc(strlen(temp)+strlen(read));

    for(i; i<strlen(temp);i++);
        line[i]=temp[i];

    for(i;i<strlen(read);i++);
        line[i+strlen(temp)] = temp[i];

    free(read);
    free(temp);

    return line; 

}

问题是,当我运行程序时,它会运行一个无限循环(我怀疑这是 main 中的 while(1)),但似乎没有打印出文本文件中的字符串。

它打印的只是:

line 1 :
line 2 :
line 3 :

... 以此类推,直到永远。

当我需要打印时,例如:

line 1 : 0
line 2 : 012345
line 3 :
line 4 : 567890

读取4行文本文件的程序示例。

坦率地说,我被困住了,不知道自己做错了什么。我已经让它打印了一些东西,但它的内容类似于 ASCII 字符 177 177 + 177 177。

这似乎指向这行代码中的错误:

line = (char*)malloc(strlen(temp)+strlen(read));

我唯一能想到的就是我的回归线;是不正确的?我在这里迷路了,将不胜感激!

【问题讨论】:

  • strlen 只能用于字符串,即以空字符结尾的字符数组。你代码中strlen的大部分用法都是错误的。
  • 是否包括转换为 char 的代码?
  • 正如@YuHao 所建议的,您对strlen 的使用在某些情况下是不正确的。例如,fgets 需要缓冲区大小。如果malloc 分配内存并且第一个字节是空终止符,那么strlen 将返回0。您传递给malloc 的内容就是您应该传递给fgets 的内容。您还应该在最后一个for 循环中将i 初始化为0,因为您使用i+strlen(temp) 作为字符索引。
  • DEFLENCHUNKSZ 为2 时,每个fgets 最多读取1 个字节,因为fgets 在读取bufsiz - 1 字节后添加了空终止符。在您的情况下,它将是DEFLEN - 1CHUNKSZ - 1,因为您应该将DEFLEN/CHUNKSZ 传递给fgets,而不是由于没有字符串读入行缓冲区而无法计算的字符串长度.如果要一次读取多个字符,则需要增加 DEFLENCHUNKSZ 的值。

标签: c malloc free fgets strlen


【解决方案1】:

需要将缓冲区扩展到读取。但是你的方法是错误的。

char *getStrFromFile(FILE *fpin){
    int i=0, ch, size=DEFLEN+1;
    if(EOF==(ch=fgetc(fpin)))
        return NULL;
    ungetc(ch, fpin);
    char *line = malloc(size);

    while(EOF!=(ch=fgetc(fpin)) && ch != '\n'){//Do not include '\n'
        line[i++] = ch;
        if(i==size-1){
            size += CHUNKSZ;
            line = realloc(line, size);
        }
    }
    line[i] = '\0';
    return line;
}

【讨论】:

  • 什么是 DEFLEN?
  • @sAguinaga 表示字符串的长度作为初始大小。
  • 这个 char 函数获取输入文件中的 1 行或所有行?
  • @sAguinaga 这个函数从输入文件中获取一行。
猜你喜欢
  • 2020-05-03
  • 2020-04-10
  • 1970-01-01
  • 2011-03-23
  • 1970-01-01
  • 2013-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多