I am writing a program that allows users to enter five names and sorts the names in Alphabet order, two adjacent names seperated by a newline character. Here is my code:
void sortWords(char s[][100], int n){
int i, j;
char *str;
for(i = 0; i < n-1; i++){
for(j = n- 1; j > i; j--){
if(strcmp(s[j], s[j-1]) == -1){
strcpy(str, s[j]);
strcpy(s[j], s[j-1]);
strcpy(s[j-1], str);
}
}
}
}
int main(){
char s[5][100];
int i;
for(i = 0; i < 5; i++){
fflush(stdin);
//gets(s[i]); // when I use this statement, my program doesn't work
scanf("%s", s[i]);
}
sortWords(s, 5);
for(i = 0; i < 5; i++){
printf("%s ", s[i]);
}
return 0;
}
When I changed the "scanf" in function main to "gets", after I have entered 5 names, the program just didn't print anything. Can anyone explain it for me, because normally, when I change one of them to the other function, I just have same results.
allows users to enter five names
Names usually have a space between the parts of the full name. scanf("%s", s)
does not read a full name, but only part of a name.
Code has many other problems too.
Difference between "gets(s);" and "scanf("%s", s);" in C
One reads a line the other reads a word.
gets()
, since C11 (2011) is no longer part of the C standard library.
Both are bad as they do not limit input and so can suffer buffer overflow.
The obsolete gets()
would read and save a line - input unto and including the '\n'
. The '\n'
is read, but not saved. If the prior input operation left a '\n'
in stdin
, then gets()
reads a short line of "\n"
and saves as ""
.
scanf("%s", s)
reads and discards any number of leading white-space characters (perhaps multiple '\n'
) and then reads and saves non-white-spaces. A following white-space stops the reading, but it is returned to stdin
for the next input function.
With common input, scanf("%s", s)
typically the leaves the final '\n'
in stdin
for the next input operation. gets()
consumes it.
Both append a null character to s
if any reading occurred.
gets()
returns a pointer. scanf()
returns a conversion count.
Recommendations
Do not use either gets(s)
nor scanf("%s", s)
in production code. To read a line, research fgets()
. To read a word, research using a width like char s[100]; scanf("%99s", s);
.
Best to test the return value of I/O functions.
Do not mix fgets()/gets()
with scanf()
functions until you understand why that is bad.
Other
if(strcmp(s[j], s[j-1]) == -1)
is poor. strcmp()
returns some negative, zero or some positive to indicate order. Better to use if(strcmp(s[j], s[j-1]) < 0)
.
strcpy(str, s[j]);
is bad as pointer str
has not been assigned a value. Better as char str[100]; strcpy(str, s[j]);
.