I take in a maximum of 100 strings from and file and place them into a 2d character array. STRING_LEN = 1000
char** read_from_file(char* fname, int * size) {
FILE *fp = fopen(fname, "r");
int lines = 0;
while(fscanf(fp, "%s", buff) != EOF) {
lines++;
}
*size = lines;
if(*size > 100) {
*size = 100;
}
rewind(fp);
char** file_array = malloc(*size * sizeof(char*));
int counter;
for(counter = 0; counter < *size; counter++) {
file_array[counter] = malloc((STRING_LEN + 1) * sizeof(char));
}
for(counter = 0; counter < *size; counter++) {
fscanf(fp, "%s", &file_array[counter]);
}
fclose(fp);
return file_array;
}
Quick sort will sort by string length.
void quick_sort(char** words, int first, int last) {
int pivot, j, i;
char *temp = malloc((STRING_LEN + 1)* sizeof(char));
if(first < last) {
pivot = first;
i = first;
j = last;
while(i < j) {
while(strlen(&words[i]) <= strlen(&words[pivot]) && i < last)
i++;
while(strlen(&words[j]) > strlen(&words[pivot]))
j--;
if(i < j) {
strcpy(temp, &words[i]);
strcpy(&words[i], &words[j]);
strcpy(&words[j], temp);
}
}
strcpy(temp, &words[pivot]);
strcpy(&words[pivot], &words[j]);
strcpy(&words[j], temp);
free(temp);
quick_sort(words, first, j-1);
quick_sort(words, j+1, last);
}
}
The quick sort function will work correctly for some files but for others the information is distorted for example. File content
car
x
house
door
ash
a
elephantback
back
After quick sort
x
a
ash
car
back
door
house
elephanthouse
As you can see the last word has been rearranged and gets worse if the file has more words. Why has strcpy combined words together like this?
You have undefined behavior in your sorting function: The expression &words[j]
returns a pointer to the pointer stored at words[j]
, ie it's the type char **
and not char *
. Remove all those address-of operator, and use only words[j]
to get a pointer to the string.
The problem here is that you're copying strings from one array to another, but each array has just enough space for the string it contains. So if for example you try to copy a 5 character string to a space with only 3 characters allocated, you overrun the allocated memory, leading to undefined behavior.
Rather than copying the full strings around, just copy the pointers:
temp = words[i];
words[i] = words[j];
words[j] = temp;
...
temp = words[pivot];
words[pivot] = words[j];
words[j] = temp;
EDIT:
Apparently I missed that all strings are allocated the same (large) amount of space. So that's not the cause of the undefined behavior. As Joachim Pileborg mentioned in his answer, using expressions like &words[j]
was the root cause.
Still, swapping the pointers as I mentioned above is more efficient than copying the actual strings, and because it addresses the same erroneous lines of code it will still fix the problem.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.