I made text file called qsort.txt and wrote arbitrary many integers in file (In my case 35 integers to be precise). My goal is to count how many integers are in that file, put them into an array defined by malloc() and sort them using qsort(). After that I want sorted numbers writen into a text file called sorted.txt.
This is my code, but obviously doesn't work as expected. Also I want to be more flexible with code so in FILE *fa = fopen(argv[1], "r+") is argv[1] so I can put any other text file to be sorted. Anyway my problem is that I don't know how to count how many integers are in file.
#include <stdio.h>
#include <stdlib.h>
int compare(const void *a, const void *b) {
if (*(int*)a < *(int*)b)
return -1;
else if (*(int*)a > *(int*)b)
return 1;
else
return 0;
}
int main(int argc, char **argv) {
FILE *fa = fopen(argv[1], "r+");
if (!fa)
exit(1);
FILE *fb = fopen("sortirano.txt", "w+");
long duljina, i;
long *ptr, *zapis;
long count = 0;
while (!feof(fa))
count++;
printf("%lu\n", count);
fseek(fa, 0, SEEK_END);
duljina = ftell(fa);
fseek(fa, 0, SEEK_SET);
ptr = (long *)malloc(sizeof(long));
while (!feof(fa)) {
fscanf(fa, "%lu", ptr);
count++;
}
printf("count: %lu\n", count);
for (i = 0; i < count; i++)
printf("%lu ", ptr[i]);
printf("\n");
free(ptr);
fclose(fa);
fclose(fb);
return 0;
}
EDIT:
This is my new code, which is simpler:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int compare(const void *a, const void *b) {
if (*(long*)a > *(long*)b)
return 1;
if (*(long*)a < *(long*)b)
return -1;
else
return 0;
}
int main() {
FILE *fa = fopen("qsort.txt", "r"); assert(fa != NULL);
FILE *fb = fopen("sorted.txt", "w+"); assert(fa != NULL);
long *ptr;
long save;
long count = 0;
long i;
long k;
while ((fscanf(fa, "%ld", &save)) == 1) //number of elements
prebroji++;
printf("count: %ld\n", count); //checking how many elements i have, just to make sure it works ok
ptr = (long *)malloc(count * sizeof(long)); //mallociranje
for (i = 0; i < count; i++)
fscanf(fa, "%ld", &ptr[i]);
for (i = 0; i < count; i++) //checking if numbers were saved at malloc array
printf("%ld ", ptr[i]);
qsort(ptr, count, sizeof(long), compare);
for (i = 0; i < count; i++) //checking if sorted correctly
printf("%ld ", ptr[i]);
for (i = 0; i < count; i++)
fprintf(fb, "%ld", ptr[i]);
printf("\n");
free(ptr);
fclose(fa);
fclose(fb);
return 0;
}
But it doesn't work: all I got are zeros printed.
Since the file only contains integers and whitespace, you can parse it with
fscanf("%ld", ...)and store the numbers into an array you reallocate on purpose as you read more numbers.Note these remarks:
Your comparison function is OK for use with
qsort.There is no need to open the files for update with
+in the mode string,nor is there any need for seeking to the end of file.
testing for end of file with
while(!feof(fa))is always wrong. You should instead test forfscanf()success and reallocate the array as needed.Here is a modified version:
EDIT:
You new code has multiple problems:
there is no need to open sorted.txt in update mode, just use
"w".you should
assert(fb)after opening the second fileprebrojishould becountyou should add
assert(ptr)after you allocate the arrayyou must add
rewind(fa);after you allocate the array to re-read the file from the beginning. This explains why you get all values as0because you do not test the return value offscanf()that returns0orEOFfor every try.it is less brittle to write
qsort(ptr, count, sizeof(*ptr), compare);to avoid size inconsistencies if you change the type of the array.similarly, writing
ptr = malloc(count * sizeof(*ptr))is more reliable as it remains consistent should you change the type ofptr.you should add a separator in
fprintf(fb, "%ld", ptr[i])to separate the numbers you write into the output file.