Hi all,
Please i'm new to C programming. i'm trying to sort words in increasing order by word size using insertion sort. A word is consecutive letters (upper or lower case)separated by other characters.
Any ideas?
Thanks.
Here are my code
Hi all,
Please i'm new to C programming. i'm trying to sort words in increasing order by word size using insertion sort. A word is consecutive letters (upper or lower case)separated by other characters.
Any ideas?
Thanks.
Here are my code
Last edited by cstyle; 03-06-2017 at 08:54 AM. Reason: attached image shows unformatted
It's far better if you just copy/paste your code between [code][/code] tags, rather than fuzzy images in a poor colour scheme.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
Code:#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<string.h> #define STRMAX 100 void wsort(char **, int); int main (int argc, char *argv[]) { int size=STRMAX; int i; char buffer[100+1]; char **wordlist; wordlist = malloc( size*sizeof(char *) ); //read in only alphabets in one line int count=0; while(scanf("%100[A-Za-z^\n]c", buffer) == 1 ) { wordlist[count] = strdup( buffer ); count += 1; if( count >= size ) { size += STRMAX; wordlist = realloc(wordlist, size*sizeof(char*)); } } for(i=0; i <= size - 1; i++) { wsort(wordlist, size); printf("%s\n", wordlist); } for(i=0; i < count; i++ ) { free(wordlist[i]); } free(wordlist); } // insertion sort void wsort (char **wordlist, int size) { int i, j; char temp[STRMAX]; for(j = 1; j < STRMAX; j++) { i = j; while( i > 0 && strlen(wordlist[i]) < strlen(wordlist [i-1]) ) { strcpy(temp, wordlist[i]); strcpy(wordlist[i], wordlist[i-1]); strcpy(wordlist[i-1], temp); i--; } } }
it compiles good but while running the program im having segmentation fault error
Likely wrong.
Might beCode:wsort(wordlist, size);
I might be off by one.Code:wsort(wordlist, count);
In other words it might be
Or evenCode:wsort(wordlist, count-1);
Code:wsort(wordlist, count-2);
Tim S.
Last edited by stahta01; 03-06-2017 at 07:46 PM.
"...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson
It's insane to use strcpy to move the strings around when you have an array of pointers! Just swap the pointers. If you copy a string from one dynamically-allocated space to another it is not guraranteed to fit in the new space.
As stahta said, you're passing "size" where you should be passing "count" in your wsort call. (However, I think it should just be passed as count and not count-1.)
In wsort, you're using STRMAX where you should use the input parameter. And changing the name of "count" to "size" in wsort is just confusing when you already have a "size" in main that means something else. (And temp should have been declared to have length STRMAX+1, but you don't need temp at all since you should just swap pointers.)
It doesn't make sense to call wsort in a loop!
In wsort, you don't need to call strlen over and over on wordlist[i] since it will always be the same.
Your scanf format is strange. I wonder what you think the ^\n part is going to do? If you show what your input looks like we can tell you how to read it properly. If there's no spaces in the "words" then a simple %100s should do.
Your realloc is in the wrong place. It needs to be before you assign the new string.
You should test the return values of malloc, realloc and strdup for failure (NULL). Technically you should use a temporary variable to receive the return value of realloc so that you still have access to the original memory if it fails.
You should have separate defines for the maximum word length and for the allocation chunk size, even if they end up having the same value.
strdup is non-standard.
You don't need unistd.h.
You don't need argc and argv.
And your code spacing is crap.
Last edited by algorism; 03-06-2017 at 08:38 PM.
The code, indented.
Next, use a compiler with lots of warnings enabled.Code:#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<string.h> #define STRMAX 100 void wsort(char **, int); int main(int argc, char *argv[]) { int size = STRMAX; int i; char buffer[100 + 1]; char **wordlist; wordlist = malloc(size * sizeof(char *)); //read in only alphabets in one line int count = 0; while (scanf("%100[A-Za-z^\n]c", buffer) == 1) { wordlist[count] = strdup(buffer); count += 1; if (count >= size) { size += STRMAX; wordlist = realloc(wordlist, size * sizeof(char *)); } } for (i = 0; i <= size - 1; i++) { wsort(wordlist, size); printf("%s\n", wordlist); } for (i = 0; i < count; i++) { free(wordlist[i]); } free(wordlist); } // insertion sort void wsort(char **wordlist, int size) { int i, j; char temp[STRMAX]; for (j = 1; j < STRMAX; j++) { i = j; while (i > 0 && strlen(wordlist[i]) < strlen(wordlist[i - 1])) { strcpy(temp, wordlist[i]); strcpy(wordlist[i], wordlist[i - 1]); strcpy(wordlist[i - 1], temp); i--; } } }
Finally, learn how to use a debugger.Code:$ gcc -Wall -g foo.c foo.c: In function ‘main’: foo.c:33:12: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=] printf("%s\n", wordlist); ^
Even if you learn nothing more than how to traverse the stack and print variables, you'll learn a lot about why it crashed.
Oopsie - NULL pointer being passed to strlen.Code:$ gdb -q ./a.out Reading symbols from ./a.out...done. (gdb) run Starting program: /home/sc/Documents/a.out hello world - Program received signal SIGSEGV, Segmentation fault. strlen () at ../sysdeps/x86_64/strlen.S:106 106 ../sysdeps/x86_64/strlen.S: No such file or directory. (gdb) bt #0 strlen () at ../sysdeps/x86_64/strlen.S:106 #1 0x0000000000400a79 in wsort (wordlist=0x602010, size=100) at foo.c:51 #2 0x00000000004008c0 in main (argc=1, argv=0x7fffffffdef8) at foo.c:32 (gdb) up #1 0x0000000000400a79 in wsort (wordlist=0x602010, size=100) at foo.c:51 51 while (i > 0 && strlen(wordlist[i]) < strlen(wordlist[i - 1])) { (gdb) info locals i = 3 j = 3 temp = "\n\000\000\000\000\000\000\000w\000\000\000|\000\000\000\300\006@\000\000\000\000\000 \033\335\367\377\177\000\000\002\000\000\000\000\000\000\000\300\006@\000\000\000\000\000\360\336\377\377\377\177", '\000' <repeats 18 times>, "\324\025\251\367\377\177\000\000\220\335\377\377\377\177\000\000\002\000\000\000\000\000\000\000\220\335\377\377" (gdb) print wordlist[i] $1 = 0x0
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.