【发布时间】:2017-03-22 18:35:16
【问题描述】:
@编辑 看起来 fread 函数读取的字符比 record_size 参数多;x
我有 2 个函数,它们按记录排序文件(冒泡排序)(键是第一个字符)。第一个是使用系统函数(读、写等),第二个是使用库函数(fread、fwrite 等)。对于小的 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
【问题讨论】:
-
我建议的第一件事是检查这些系统调用中是否有任何失败以及原因。像
if( fread(...) != record_size ) { perror("fread failed to read sufficient data") }这样的东西。fseek和fwrite相同。 -
抱歉,我无法重现您的问题。我制作了一个包含 5 行的文件,每行以一个数字开头,然后是 4999 x。两者都运行良好。
-
我刚刚做了测试,没有打印错误。对于 record_size = 5000 和 num_or_record = 10 的 lib_sort 仍然不起作用。
-
请用这些测试编辑你的代码。您能否详细说明什么“不起作用”?还要说明你是如何调用这些函数的。
-
结果文件只有更少的行和不同的行长度(多于和少于 5000)。我发现了一个错误,它读取的字符比我的 record_size 参数多,我在 buffer1 的末尾有这样的东西:jfuhaypwjgsgjxl\021\020