c - 具有动态分配内存的 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);
}
}
}
}
}
解决方案
您的代码存在一些问题,几乎没有一个是致命的,这取决于您传递给函数的内容。
灾难性失败可能是因为在您的
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
,您只能修复这些问题,并且代码可能会起作用,我仍然建议其他修复。
推荐阅读
- android - 如何在 tess-two 中加载数字训练数据?
- c - 64 位长整型参数
- amazon-web-services - AWS lambda 用于从 s3 到 rds 的自动还原
- sql - 尝试在一行中显示从不同条目存储的 REPLACED 和 ORIGINAL 值(在不同列下)
- python - Seaborn - 通过直方图中的一个因子修改 y 轴
- f# - 从擦除类型引用生成的类型
- json - 如何在 httpie 中发送包含引号的 POST 请求?
- scheme - 检查 K 组合器的绑定变量失败
- sql - 如何在数据库项目中的部署后脚本和部署前脚本之间共享项目版本号
- java - SpringBoot 日志记录 - 每个日志语句中的堆栈跟踪