首页 > 解决方案 > 具有动态分配内存的 fscanf 文本文件

问题描述

我必须做一个读取带有字符的文本文件的函数。必须使用 malloc 和 realloc。我编写了这段代码,没有出现错误,但是当我尝试读取文件时,出现运行时错误。而且我不明白这段代码的问题出在哪里。

void openFile(FILE** file,char* filename)
{
int SIZE=10;
char* data,*data2;
int n = 0;
char c;
printf("filename:");
scanf("%s",&*filename);
if (!((*file) = fopen(filename, "r")))
    perror("Error:");
else
{   
    if ((data = (char*)malloc(SIZE * sizeof(char))) == NULL)
    {
        perror("malloc:");
    }   
    while (fscanf((*file),"%s",c) != EOF)
    {
        if (n < SIZE)
        {
            data[n++] = c;
        }
        else
        {
            if ((data2 = (char*)realloc(data, SIZE * sizeof(char))) != NULL)
            {
                data = data2;
                data[n++] = c;  
            }
            else
            {
                free(data);
            }
        }

    }
}
}

标签: c

解决方案


您的代码存在一些问题,几乎没有一个是致命的,这取决于您传递给函数的内容。

  • 灾难性失败可能是因为在您的fscanf函数中您使用"%s"带有char变量的说明符,正确的说明符是%c,并且您需要传递变量的地址&c

  • 您应该解决scanf("%s", &*filename);,存在数据超出内存缓冲区存储容量的危险,您应该始终定义不大于缓冲区容量的最大大小,您可以使用"%99s"说明符 withscanf用于 100 个字符的内存缓冲区,或者更好的是,使用fgets

   fgets(filename, sizeof(filename), stdin);
   filename[strcspn(filename, "\n")] = '\0'; //to remove newline character
  • 您使用文件指针的方式让我怀疑您不需要将它作为参数传递,更不用说作为双指针传递,如果您需要将指向文件流的指针保留在函数之外,这将很有用,如果是这种情况,您可以保持原样,否则您可以使用局部变量并在完成后关闭流。

这是他的代码,上面提到了一些更正,还有一些其他的小修正:

void openFile(char *filename)
{
    int SIZE = 10;
    char *data, *data2;
    int n = 0;
    char c;
    FILE *file; //local variable
    printf("filename:");
    scanf("%99s", filename);// &* is pointless, using %99s, assuming filename[100]
    if (!(file = fopen(filename, "r")))
        perror("Error:");
    else
    {
        if ((data = malloc(SIZE)) == NULL) //char size is always 1 byte, no cast needed, include stdlib.h
        {
            perror("malloc:");
        }
        while (fscanf(file, "%c", &c) != EOF) //specifier for char is %c, furthermore you need & operator
        {                                     //probably the source of your problems
            if (n < SIZE)
            {
                data[n++] = c;
            }
            else
            {
                if ((data2 = realloc(data, SIZE)) != NULL) // again no cast, no sizeof(char)
                {
                    data = data2;
                    data[n++] = c;
                }
                else
                {
                    free(data);
                }
            }
        }
        fclose(file); //close file stream
    }
}

请注意,唯一的灾难性问题是带有 的问题fscanf,您只能修复这些问题,并且代码可能会起作用,我仍然建议其他修复。


推荐阅读