@EDIT Looks like fread function reads more characters than record_size parameter ;x
I've got 2 functions which sort file(bubble sort) by records(key is first character). The first one is using system functions(read, write, etc.) and secong is using library functions(fread, fwrite, etc.). For small record_size parameter both works well but e.g for record_size = 5000 only sys_sort works properly. File sorted by lib_sort has less lines and different lengths. Why? I don't know what is the problem.
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);
}
And this is the correct one:
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);
}
I use ubuntu 16.04 and standard C99