我有以下代码尝试读取文本文件,进行备份,并将读取文件字符串传递给进一步的处理例程。我所看到的行为是非常意外的。
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+
,具体取决于最初编写该文件的代码中的某些情况。
我认为这个概念非常简单:
有两个令人不安的症状:
很简单,到底是怎么回事?
答案 0 :(得分:2)
为什么你用fread()阅读并用fprintf()而不是fwrite()写?你使用fprintf()的方式,你受到文件中第一个%
符号的摆布(格式字符串漏洞)。
此外,请确保两个文件都以相同模式打开(文本模式与二进制模式)。通常,fread()/ fwrite()倾向于与二进制模式一起使用。
答案 1 :(得分:2)
这一行不太好:
13: fprintf(PPLBackup, fileContent);
如果文件包含%s
之类的字符序列,那么fprintf
将在堆栈中查找其他数据。
您应该使用fwrite
代替:
13: fwrite(fileContent, fsize, 1, PPLBackup);
或者至少这样做:
13: fprintf(PPLBackup, "%s", fileContent);
答案 2 :(得分:0)
这个完整的程序适用于Linux。它有Klas的改动。注意我必须使用fsize作为全局因为传递要复制的文件的char *内容如果稍后strlen'd则会破坏 - 原因很明显
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
unsigned long fsize=0L;
char *get_file(FILE *PPLFile) {
rewind(PPLFile);
fseek(PPLFile, 0, SEEK_END);
fsize = ftell(PPLFile);
char *string = (char*)calloc(fsize + 1, sizeof(char));
rewind(PPLFile);
fread(string, sizeof(char), fsize, PPLFile);
return string;
}
void write_file(char *basePath, char *fileContent) {
FILE* PPLBackup;
char* fileSuffix = ".backup";
char* PPLBackupLocation = (char*)calloc(strlen(basePath) + strlen(fileSuffix) + 1, sizeof(char));
strcpy(PPLBackupLocation, basePath);
strcat(PPLBackupLocation, fileSuffix);
PPLBackup = fopen(PPLBackupLocation, "w");
fwrite(fileContent, fsize, 1, PPLBackup);
fclose(PPLBackup);
free(PPLBackupLocation);
}
答案 3 :(得分:0)
多个问题
正如@KlasLindbäck&amp; amp; @Medinoc,请勿使用fprintf()
。 fwrite()
要好得多。
@KlasLindbäck说,确保在二进制模式下打开两个文件读写。如fopen(PPLBackupLocation, "wb")
。
应评估fread()
的返回值,如果好,则用于fwrite()
。
calloc(fsize + 1, sizeof(char))
无需添加1.