我有以下代码尝试读取文本文件,进行备份,并将读取的文件字符串传递给进一步的处理例程。我看到的行为非常出乎意料。
01: rewind(PPLFile);
02: fseek(PPLFile, 0, SEEK_END);
03: unsigned long fsize = ftell(PPLFile);
04: char *string = (char*)calloc(fsize + 1, sizeof(char));
05: rewind(PPLFile);
06: fread(string, sizeof(char), fsize, PPLFile);
07: FILE* PPLBackup;
08: char* fileSuffix = ".backup";
09: char* PPLBackupLocation = (char*)calloc(strlen(basePath) + strlen(fileSuffix) + 1, sizeof(char));
10: strcpy(PPLBackupLocation, basePath);
11: strcat(PPLBackupLocation, fileSuffix);
12: PPLBackup = fopen(PPLBackupLocation, "w");
13: fprintf(PPLBackup, fileContent);
14: fclose(PPLBackup);
15: free(PPLBackupLocation);
文件句柄*PPLFile
之前已使用w+
或a+
标志打开,具体取决于之前编写的代码中的某些情况最初文件。
我认为这个概念很简单:
- 将指针移过文件末尾并感知其位置以确定文件大小(以字节为单位)
- 创建字节大小加一的空字符串(作为空终止符)
- 倒回整个文件内容并将其读取到字符串中,直到检测到的文件大小
- 创建备份文件名和文件指针
- 将从原始文件读取的整个字符串写入新的备份文件。
- 关闭备份文件并继续处理读取的字符串
有两个令人不安的症状:
- 包含原始文件的 *char 字符串有更多的零(文本文件中的数千个 ~=20MB),因此最后一个非零值可能距离末尾 3000 个字节。看起来比原始文件小。
- 写入备份文件时,生成的文件比原始文件稍大一些,并在末尾附加了原始文件的看似随机的额外样本,同样是几千字节。
很简单,到底发生了什么?
最佳答案
这一行不好:
13: fprintf(PPLBackup, fileContent);
如果文件包含像 %s
这样的字符序列,那么 fprintf
将在堆栈上查找其他数据。
您应该使用fwrite
来代替:
13: fwrite(fileContent, fsize, 1, PPLBackup);
或者至少这样做:
13: fprintf(PPLBackup, "%s", fileContent);
关于c - 读取/备份文本文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19000108/