# Thread: C Sorting Array

1. ## C Sorting Array

Hi all

Here is my problem. I wrote a program that asks the user the input 10 different words. After the words are input, it then mirrors the words, as well as changes the upper/lower case and prints it out like the following for example.

Type word 1: Word
Type word 2: tEST
Type word 3: aGaIN
....... and so on until word 10

Unsorted Output

DROwwORD
tseTTest
niAgAAgAin

Now my problem is that I have to take the unsorted output, and sort it in ascending order.
Here is a snippet of my code posted here if someone could take a look at it, and see if they can come up with some help.

Code:
``` #include <stdio.h>
#include <string.h>

int main(void)
{
char Word[10][19];
int i, j, k, l, z;
int value;
int str;
char ch;

for(z=0 ; z<10 ; z++)
{
if (z == 0)
printf("Enter the 1st word: ");
else if (z == 1)
printf("Enter the 2nd word: ");
else if (z == 2)
printf("Enter the 3rd word: ");
else
printf("Enter the &#37;dth word: ",z+1);
i=0;
while(( ch = fgetc(stdin)) != '\n')
{
i=i+1;
Word[z][i]= ch;

}
l=10;
for(k=i ; k>=1; k--)
{
Word[z][l]=Word[z][k];
l=l++;
}
Word[z][19]=i;
}
printf("\n");
printf("Unsorted Input: \n");
printf("\n");
for (z=0 ; z<10 ; z++)
{
for(j=10 ; j<=9+Word[z][19]; j++)
{
value = Word[z][j];
if (value >= 97 && value<=122)
{ value = value - 32; }
else if (value >=67 && value<=90)
{ value = value + 32; }
printf("%c", value);
}
for(j=1; j<=Word[z][19]; j++)
{
value = Word[z][j];
if (value >= 97 && value<=122)
{ value = value - 32; }
else if (value >=67 && value<=90)
{ value = value + 32; }
printf("%c", value);
}
putchar('\n');
}
printf("\n");
printf("Sorted Input: \n");
printf("\n");

}```
Anything is greatly appreciated.

2. Right no body is going to help you out, if your code is not intended properly. You have a horrible indentation. Start with first indenting your code.

ssharish

3. Welcome to the board, now let's get down to business:

You'll HAVE to learn and practice good indentation. Do it now, and save yourself a TON
of work. Also, it's tough to get help without it.

Code:
```if(nixon practices better styling)   {
printf("\n He'll get more help");
frustration--;
}

if(nixon practices better styling)
{
printf("\n He'll get more help");
frustration--;
}```
Either of the above are OK. Anything else - beware.

Also, I'd like to see your try with a bubblesort on this. If you get stuck, we're happy to help with the particulars, but just saying "It needs this feature", and making no try to do this bubblesort (or whatever), on your own, doesn't cut much mustard.

We are not a homework or project feature request, service. We give technical advice to YOUR work, not ours.

4. Ok, so I re-indented to the best of my ability (first programming experience ever), and I also added in my attempt at the bubble sort down at the bottom.

Thanks

Code:
``` #include <stdio.h>
#include <string.h>

int main(void)
{
char Word[10][19];
int i, j, k, l, z;
int value;
int str;
char ch;

for(z=0 ; z<10 ; z++)
{
if (z == 0)
printf("Enter the 1st word: ");
else if (z == 1)
printf("Enter the 2nd word: ");
else if (z == 2)
printf("Enter the 3rd word: ");
else
printf("Enter the &#37;dth word: ",z+1);

i=0;

while(( ch = fgetc(stdin)) != '\n')
{
i=i+1;
Word[z][i]= ch;

}

l=10;

for(k=i ; k>=1; k--)
{
Word[z][l]=Word[z][k];
l=l++;
}
Word[z][19]=i;
}

printf("\n");
printf("Unsorted Input: \n");
printf("\n");

for (z=0 ; z<10 ; z++)
{
for(j=10 ; j<=9+Word[z][19]; j++)
{
value = Word[z][j];
if (value >= 97 && value<=122)
{
value = value - 32;
}
else if (value >=67 && value<=90)
{
value = value + 32;
}
printf("%c", value);
}

for(j=1; j<=Word[z][19]; j++)
{
value = Word[z][j];
if (value >= 97 && value<=122)
{
value = value - 32;
}
else if (value >=67 && value<=90)
{
value = value + 32;
}
printf("%c", value);
}
putchar('\n');
}

printf("\n");
printf("Sorted Input: \n");
printf("\n");

/* Here is my attempt at the bubble sort for the 2dim char array */

for(i=0;i<l-1;i++) /* Not sure what for statements to grab from my code */
for(j=l-1;j>i;j--)
{
if(strcmp(Word[j],Word[j-1])<0)
{
strcpy(temp,Word[j]);
strcpy(Word[j],Word[j-1]);
strcpy(Word[j-1],temp);
}
}

for(i=0;i<l;i++) printf("%s\n",Word[z][j]);

scanf("%c", Word[z][j]);

}```

5. you still have a problematic indenttion
do you have maximum warning level?
Code:
`		while(( ch = fgetc(stdin)) != '\n')`
fgetc returns int
compiler warns you
Code:
`test.c(26) : warning C4244: '=' : conversion from 'int' to 'char', possible loss of data`
your ch should be declared as int and you should check that it is not EOF

Code:
`test.c(90) : error C2065: 'temp' : undeclared identifier`
you should declare all your variables

Code:
`Word[z][19]=i;`
it is out of bouds access - your array has only 19 chars so valid indexes are from 0 to 18

Code:
```if (value >= 97 && value<=122)
{
value = value - 32;
}
else if (value >=67 && value<=90)
{
value = value + 32;
}```
do not use magic numbers

strcmp and strcpy work with nul-terminated strings, I do not see that you put nul-char at the end of your strings

6. There are lots of aesthetic things I would do here. I'd break out the input fetching parts and sort parts into functions, at minimum. If for some reason you aren't allowed to do that or can't yet, then do yourself a favor and concentrate on one task at a time. Don't write the whole program in one go yet. Despite how simple this may be, you are learning, like all of us.

Along the lines of the "do not use magic numbers" advice that vart gave, I would free yourself from the fact that a character has a corresponding integer value. If you were me, you'd do something like this:
Code:
```#include <limits.h>
#include <string.h>

int bar_tolower ( int foo )
{
#define LOWER "abcdefghijklmnopqrstuvwxyz"
#define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
const char * const upper = UPPER;
/** Find location of uppercase letter **/
const char * lower = ( foo <= CHAR_MAX && foo > '\0' ) ? strchr( upper, foo ) : NULL;

/** Return the character in the same position in the opposite string **/
return ( lower != NULL ) ? LOWER[lower - upper] : foo;
#undef LOWER
#undef UPPER
}

int bar_toupper ( int foo )
{
#define LOWER "abcdefghijklmnopqrstuvwxyz"
#define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
const char * const lower = LOWER;
/** Find location of lowercase letter **/
const char * upper = ( foo <= CHAR_MAX && foo > '\0' ) ? strchr( lower, foo ) : NULL;

/** Return the character in the same position in the opposite string **/
return ( upper != NULL ) ? UPPER[upper - lower] : foo;
#undef LOWER
#undef UPPER
}```
But that's simply an idea, there are numerous O.K. ways. Preferring character constants over integer constants would be a step in the right direction I think.

Once you fix the zero termination problem that vart mentioned in his earlier post, I'm fairly sure that bubble sort will be working.

Nice work.

7. Once you fix the zero termination problem that vart mentioned in his earlier post, I'm fairly sure that bubble sort will be working.
Im not to sure where exactly I fix the zero termination problem. Is this referring to the null character thats placed at the end of each word?

8. Yes. The Standard C library expects that you are working with '\0' terminated strings. That zero acts as a dummy character, marking the end of your strings. Without it, you will not be able to copy them, figure out how long they really are or even print them correctly.

It's easy to fix:
1. call memset on your strings to fill them with '\0' before you use them, which will always maintain the zero terminator, or
2. add '\0' to the end yourself after you've read the word.

9. Nixonbw,

As far as indenting goes, if you are lazy and do not know the details of indention, you may want to try out the gnu indent tool:

http://www.gnu.org/software/indent/

The man page gives more details on its use.

10. Originally Posted by vart
do you have maximum warning level?
Code:
`		while(( ch = fgetc(stdin)) != '\n')`
fgetc returns int
compiler warns you
Code:
`test.c(26) : warning C4244: '=' : conversion from 'int' to 'char', possible loss of data`
your ch should be declared as int and you should check that it is not EOF
GCC doesn't complain about narrowing implicit conversions...
So not all compilers does.

11. Also per the ISO standard for fgetc

If the integer value returned by fgetc() is stored into a variable of type char and then compared against the integer constant EOF, the comparison may never succeed, because sign-extension of a variable of type char on widening to integer is implementation-defined.

The ferror() or feof() functions must be used to distinguish between an error condition and an end-of-file condition.

http://www.opengroup.org/onlinepubs/...ons/fgetc.html

12. Originally Posted by Elysia
GCC doesn't complain about narrowing implicit conversions...
So not all compilers does.
Then use some more robast compiler. Intel's is free for linux and does complain
Microsoft's is free for windows and does complain. Why to use compiler which does not do its work as it should?

13. Tell that to those who use GCC. I don't like it. I use Visual Studio.

14. Tell that to those who use GCC. I don't like it. I use Visual Studio.
I use gcc, and had never had any use for that warning. I think it is a fine compiler, with a lot of years of work on it, and an assortment of tools that integrate well with it.
I believe someone with a background of a few years in programming doesn't generally do such errors except if one means to. The only time such warnings would look nice would be usually either on teaching C or while learning C, and i had an embarassing moment with gcc's port mingw32 when i was showing someone implicit conversions and thought it would warn or not even let me build. But silence was surprising at that time.

15. Why to use compiler which does not do its work as it should?
gcc is doing its work just as it should, but it is not doing its work just as it could, since compilers are not required to warn about such conversions.

Popular pages Recent additions