[SOLVED] Difference between "gets(s);" and "scanf("%s", s);" in C


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++){
        //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.


  • 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.


  • 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]);.

Answered By – chux – Reinstate Monica

Answer Checked By – Robin (BugsFixing Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *