在C中逐字符读取文件

问题描述 投票:33回答:7

我正在用C语言编写BF解释器,并且在读取文件时遇到了问题。我曾经使用scanf来读取第一个字符串,但随后您的BF代码中不能包含空格或注释。

现在这里是我所拥有的。

char *readFile(char *fileName)
{
  FILE *file;
  char *code = malloc(1000 * sizeof(char));
  file = fopen(fileName, "r");
  do 
  {
    *code++ = (char)fgetc(file);

  } while(*code != EOF);
  return code;
}

我知道问题在于如何将文件中的下一个字符分配给代码指针,但是我不确定那是什么。我的指针知识不足,这是此练习的重点。解释器工作正常,全部使用指针,我只是在读取文件时遇到问题。

((稍后我将实现仅将+-><[].,读取到文件中,尽管如果有人有好的方法可以做到这一点,如果您让我知道,那就太好了!)

c file-io io iostream
7个回答
41
投票

您的代码有很多问题:

char *readFile(char *fileName)
{
    FILE *file;
    char *code = malloc(1000 * sizeof(char));
    file = fopen(fileName, "r");
    do 
    {
      *code++ = (char)fgetc(file);

    } while(*code != EOF);
    return code;
}
  1. 如果文件大于1,000字节怎么办?
  2. 您每次读取一个字符都在增加code,然后将code返回给调用者(即使它不再指向malloc返回的存储块的第一个字节) 。
  3. 您正在将fgetc(file)的结果强制转换为char。您需要先检查EOF,然后再将结果转换为char

维护malloc返回的原始指针很重要,以便以后可以释放它。如果我们忽略文件大小,则可以通过以下方法实现此目的:

char *readFile(char *fileName)
{
    FILE *file = fopen(fileName, "r");
    char *code;
    size_t n = 0;
    int c;

    if (file == NULL)
        return NULL; //could not open file

    code = malloc(1000);

    while ((c = fgetc(file)) != EOF)
    {
        code[n++] = (char) c;
    }

    // don't forget to terminate with the null character
    code[n] = '\0';        

    return code;
}

有各种各样的系统调用,它们会给您文件的大小;常见的是stat


8
投票

从@dreamlax扩展上面的代码

stat

这将为您提供文件的长度,然后继续逐个字符地读取它。


2
投票

[我认为最重要的问题是,在读入内容时,您要递增char *readFile(char *fileName) { FILE *file = fopen(fileName, "r"); char *code; size_t n = 0; int c; if (file == NULL) return NULL; //could not open file fseek(file, 0, SEEK_END); long f_size = ftell(file); fseek(file, 0, SEEK_SET); code = malloc(f_size); while ((c = fgetc(file)) != EOF) { code[n++] = (char)c; } code[n] = '\0'; return code; } ,然后返回code的最终值,即您将返回指向code,然后将其返回。此外,C字符串需要以空值结尾。您需要确保将code直接放在读入的最后一个字符之后。

注意:

您可以使用'\0'一击获得整行。

2
投票
这里是一种简单的方法,可忽略除有效的操心角色之外的所有内容:

2
投票
文件的每次调用也正在打开而不是关闭

1
投票
两者中的任何一个都可以解决问题-

1
投票
这里的问题是双重的
© www.soinside.com 2019 - 2024. All rights reserved.