@EDIT 看起来像fread函数读取比record_size参数更多的字符; x
我有2个按记录排序文件(冒泡排序)的功能(键是第一个字符)。第一个是使用系统函数(读,写等),而secong正在使用库函数(fread,fwrite等)。对于small record_size参数,两者都运行良好,但对于record_size = 5000,只有sys_sort才能正常工作。按lib_sort排序的文件具有较少的行和不同的长度。为什么?我不知道这是什么问题。
void lib_sort(const char *filename, long long int record_size, long long int num_of_lines) {
record_size++; // '\n' char at the end of line
FILE *file;
if (!(file = fopen(filename, "r+"))) {
printf("Cannot open %s file.\n", filename);
fclose(file);
exit(EXIT_FAILURE);
}
char *buffer1 = malloc(sizeof(char) * record_size);
char *buffer2 = malloc(sizeof(char) * record_size);
bool flag = true;
while (flag) {
flag = false;
if(fseek(file, 0, SEEK_SET) != 0) {
printf("fseek failed.\n");
}
if((fread(buffer1, sizeof(char), (size_t) record_size, file)) != record_size) {
printf("fread failed.\n");
}
for (int i = 1; i < num_of_lines; ++i) {
if((fread(buffer2, sizeof(char), (size_t) record_size, file)) != record_size) {
printf("fread failed.\n");
}
if (buffer1[0] > buffer2[0]) {
if(fseek(file, record_size * (-2), SEEK_CUR) != 0) {
printf("fseek failed.\n");
}
if((fwrite(buffer2, sizeof(char), (size_t) record_size, file)) != record_size) {
printf("fwrite failed.\n");
}
if((fwrite(buffer1, sizeof(char), (size_t) record_size, file)) != record_size) {
printf("write failed.\n");
}
flag = true;
} else {
char *tmp = buffer2;
buffer2 = buffer1;
buffer1 = tmp;
}
}
num_of_lines--;
}
fclose(file);
free(buffer1);
free(buffer2);
}
这是正确的:
void sys_sort(const char *filename, long long int record_size, long long int num_of_records) {
record_size++; // '\n' char at the end of line
int file;
if ((file = open(filename, O_RDWR)) < 0) {
printf("Cannot open %s file.\n", filename);
close(file);
exit(EXIT_FAILURE);
}
char *buffer1 = malloc(sizeof(char) * record_size);
char *buffer2 = malloc(sizeof(char) * record_size);
bool flag = true;
while (flag) {
flag = false;
lseek(file, 0, SEEK_SET);
read(file, buffer1, (size_t) record_size);
for (int i = 1; i < num_of_records; ++i) {
read(file, buffer2, (size_t) record_size);
if (buffer1[0] > buffer2[0]) {
lseek(file, record_size * (-2), SEEK_CUR);
write(file, buffer2, (size_t) record_size);
write(file, buffer1, (size_t) record_size);
flag = true;
} else {
char *tmp = buffer2;
buffer2 = buffer1;
buffer1 = tmp;
}
}
num_of_records--;
}
close(file);
free(buffer1);
free(buffer2);
}
我使用的是ubuntu 16.04和标准C99
答案 0 :(得分:0)
您错误地使用了fread()
和fwrite()
。
size_t fread(void *ptr, size_t size, size_t nmemb, FILE * stream );
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
<强>描述强>
函数
fread()
从nmemb
指向的流中读取size
个数据元素,每个stream
个字节长,将它们存储在{ptr
给出的位置1}}。函数
fwrite()
将nmemb
个数据元素(每个size
个字节长)写入stream
指向的流,从{ptr
给出的位置获取它们1}}。
您告诉fread()
和fwrite()
您的记录或项目的长度为1个字节,并且您要求提供5000条记录。
返回值
成功时,
fread()
和fwrite()
会返回读取或写入的项目数 。此数字等于仅在大小为1
时传输的字节数。如果发生错误,或者到达文件末尾,则返回值为短项目计数(或零)。
您传递给fread()
和fwrites()
的参数在您的代码中的顺序错误,您明确表示记录大小(项目的长度)为record_size
或5000失败的情况。
您应该以这种方式编写代码来调用fread()
:
fread(buffer1, (size_t) record_size, 1, file)
并以这种方式致电fwrite()
:
fwrite(buffer2, (size_t) record_size, 1, file)
还应注意fread()
和fwrite()
适用于二进制流。这意味着字符串不会自动为空终止,并且读取将读取过去的换行符并超过空\0
个字节。写入时,换行符不会自动转换为操作系统支持的换行符,例如Linux上的LF
和Windows上的CRLF
。
对于字符串操作,请改用fgets()
和fputs()
。
您忘了提及我错误地认为您在Linux上运行。根据您的评论,您毕竟在Windows上运行。在Windows上,fread()
和fwrite()
在text
模式下打开时由于与操作系统相关的编码转换而无法正常工作。您需要以binary
模式打开文件。
答案 1 :(得分:0)
我在每个fseek(file, 0, SEEK_CUR);
和fread()
函数之后添加了fwrite()
,这对我有用。我不知道为什么。