Am I not doing that right now? That's what I'm attempting, at least...
Am I not doing that right now? That's what I'm attempting, at least...
Alright! I finally got the code mostly working.
The only problem is that the last line of my output gets \377 appended to it. It's definitely happening either when the data is being read or shortly after.Code:#include <stdio.h>#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <stdlib.h> #include <string.h> int filesize(char * filename) { struct stat status; if (stat(filename, &status) == -1) { return -1; } else { return (int) status.st_size; } } int compare(const void *elem1, const void *elem2) { char **e1 = (char **) elem1; char **e2 = (char **) elem2; if (strcmp(*e1,*e2)<0) return -1; else if (strcmp(*e1,*e2)>0) return 1; else return 0; } void sort(char **array, int size) { qsort(&array[0], size, sizeof(array[0]), &compare); } int main(int argc, char * argv[]) { FILE *read; char in_name[255]; int n = 0; int j = 0; int linecount = 1; printf("What file should be read?\n"); if (scanf("%s", in_name) != 1) { printf("Invalid input.\n"); return 1; } read = fopen(in_name,"r"); if (read == NULL) { printf("Cannot open input file.\n"); return 1; } char * data = malloc(filesize(in_name)); data[n] = fgetc(read); while (data[n] != EOF) { if (data[n] == '\n') { data[n] = '\0'; linecount++; } data[++n] = fgetc(read); } if (data[n] != '\0') data[++n] = '\0'; char ** lines = malloc(sizeof(lines[0]) * linecount); int i = 0; while (j < linecount) { lines[j] = &data[i]; while(data[i] != '\0') i++; i++; j++; } sort(lines,linecount); for (int k = 0; k < linecount; k++) { printf("%s\n", lines[k]); } fclose(read); free(data); free(lines); return 0; }
In the future, please post your code in plain text. That way it will use the forum's default font and syntax highlighting, which will make it easier for us to read.
As to the problem, I had your program print linecount, to see what it thinks it is, and compared that to the actual line count:
So you see, linecount 1 more than it should be. Perhaps initialize it to something else.Code:$ wc -l raven.txt 125 raven.txt $ ./foo What file should be read? raven.txt linecount = 126
EDIT: Since strcmp has the same return behavior that qsort expects, your compare function could simply be
Code:int compare(const void *elem1, const void *elem2) { char **e1 = (char **) elem1; char **e2 = (char **) elem2; return strcmp(*e1,*e2); }
Last edited by anduril462; 11-20-2013 at 12:22 PM.
Ah, thank you so much! I've fixed it (as well as the over-complicated sort) and everything runs perfectly now.
For the final time, in case anyone needs it later, here's my code.
Code:#include <stdio.h>#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <stdlib.h> #include <string.h> int filesize(char * filename) { struct stat status; if (stat(filename, &status) == -1) { return -1; } else { return (int) status.st_size; } } int compare(const void *elem1, const void *elem2) { char **e1 = (char **) elem1; char **e2 = (char **) elem2; return strcmp(*e1,*e2); } void sort(char **array, int size) { qsort(&array[0], size, sizeof(array[0]), &compare); } int main(int argc, char * argv[]) { FILE *read; char in_name[255]; int n = 0; int j = 0; int linecount = 0; printf("What file should be read?\n"); if (scanf("%s", in_name) != 1) { printf("Invalid input.\n"); return 1; } read = fopen(in_name,"r"); if (read == NULL) { printf("Cannot open input file.\n"); return 1; } char * data = malloc(filesize(in_name)); data[n] = fgetc(read); while (data[n] != EOF) { if (data[n] == '\n') { data[n] = '\0'; linecount++; } data[++n] = fgetc(read); } if (data[n] != '\0') data[++n] = '\0'; char ** lines = malloc(sizeof(lines[0]) * linecount); int i = 0; while (j < linecount) { lines[j] = &data[i]; while(data[i] != '\0') i++; i++; j++; } sort(lines,linecount); for (int k = 0; k < linecount; k++) { printf("%s\n", lines[k]); } fclose(read); free(data); free(lines); return 0; }