Nuggets10 Nuggets10 - 16 days ago 5
C Question

Sorting user input in lexicographical returning memory characters?

I am attempting to alphabetically sort user input with a maximum of 10,000 words and a max length of 25 words. I am using 'stop' to end user input prematurely which is running me into some issues. The current program results in the following as output when I try to input hello stop

▒l▒
0▒l▒
A{▒
e▒



▒&
▒▒
▒▒
▒▒
▒▒
▒l▒
▒l▒
▒▒;
▒Se▒









▒!
Ќl▒



▒.X




I am assuming this has to do with my memory allocation but I am not too sure and couldn't find some answers regarding this. Any help would be appreciated, the following is my code (feel free to ignore the lowercase pointer, still working on getting the output to turn into lowercases!)

#include<stdio.h>
#include <string.h>

//for using tolower
#include <ctype.h>
int main() {
int i, k, j;
char abc[25];
const char *stop = "stop";
char *p; //using for lowercase
//using 2d array for max of 10,000 words, max size of words 25
char str[10000][25], temp[25];

printf("Enter up to 10000 words, type stop to enter the current words:\n");
while (strncmp(abc, "stop", 5) != 0) {
scanf("%s", abc);
}
//for (i = 0; i < 10000; ++i)
//scanf("%s[^\n]", str[i]);

for (i = 0; i < 10000; ++i)
for (k = i + 1; k < 10000; ++k) {
//comparing two strings using strcmp() function is used
//using strcpy() to copy string to a temp
if (strcmp(str[i], str[k]) > 0) {
strcpy(temp, str[i]);
strcpy(str[i], str[k]);
strcpy(str[k], temp);
}
}

//using pointer to converting to lowercase
//src: https://www.daniweb.com/programming/software-development/threads/57296/how-does-one-tolower-an-entire-string
for (p = str; *p != '\0'; p++)
*p = (char) tolower(*p);

//printing words in lexi order
printf("\nWords in lexicographical order: \n");
for (i = 0; i < 10000; ++i) {
puts(str[i]);
}
printf("WARNING: Words longer than 25 in length were ignored. \n");

return 0;

}

Answer

The code has the following serious issues:

  • the str array of string is not initialized. It may contain full garbage, including strings with no null terminator.
  • later statements iterate through all these garbage strings, which might (and does in general) not end so well...
  • your "lowering" loop as you don't processes the array of strings as if it was a single string.
  • you read a lot of strings in a temporary variable, but you don't do anything with them.

To solve this, you need to keep track of the number of items in your arrays and iterate only through the valid strings:

int n=0;
while (scanf("%24s", abc)>0 && strncmp(abc, "stop", 5) != 0) {
    strncpy (str[n++], abc, 25); 
}

for (i = 0; i < n; ++i)
     for (k = i + 1; k < n; ++k) {
         ...
     }
     ...
}
for (i =0; i<n; i++) 
    for (p = str[i]; *p != '\0'; p++)
        *p = (char) tolower(*p);
...
for (i = 0; i < n; ++i) {
        puts(str[i]);
}
...

Here an online demo