Categories
c strcmp string

How do I properly compare strings in C?

233

I am trying to get a program to let a user enter a word or character, store it, and then print it until the user types it again, exiting the program. My code looks like this:

#include <stdio.h>

int main()
{
    char input[40];
    char check[40];
    int i=0;
    printf("Hello!\nPlease enter a word or character:\n");
    gets(input);   /* obsolete function: do not use!! */
    printf("I will now repeat this until you type it back to me.\n");

    while (check != input)
    {
        printf("%s\n", input);
        gets(check);   /* obsolete function: do not use!! */
    }

    printf("Good bye!");
    

    return 0;
}

The problem is that I keep getting the printing of the input string, even when the input by the user (check) matches the original (input). Am I comparing the two incorrectly?

5

345

You can’t (usefully) compare strings using != or ==, you need to use strcmp:

while (strcmp(check,input) != 0)

The reason for this is because != and == will only compare the base addresses of those strings. Not the contents of the strings themselves.

7

  • 11

    the same in java,which may just compare with the address.

    – Telerik

    Sep 6, 2014 at 16:29

  • 36

    Writing while (strcmp(check, input)) is sufficient and is considered good practice.

    – Shravan

    Jun 28, 2015 at 15:53

  • know more…codificare.in/codes/c/…

    Jun 25, 2016 at 9:55

  • 10

    It is safer to use strncmp! Don’t want a buffer overflow!

    – Floam

    Nov 10, 2017 at 18:36

  • 2

    @craigB Sorry to burst your bubble, but strcmp() says "abcde" is bigger than "abc", not equal to it.

    Sep 11, 2020 at 14:22

38

Ok a few things: gets is unsafe and should be replaced with fgets(input, sizeof(input), stdin) so that you don’t get a buffer overflow.

Next, to compare strings, you must use strcmp, where a return value of 0 indicates that the two strings match. Using the equality operators (ie. !=) compares the address of the two strings, as opposed to the individual chars inside them.

And also note that, while in this example it won’t cause a problem, fgets stores the newline character, '\n' in the buffers also; gets() does not. If you compared the user input from fgets() to a string literal such as "abc" it would never match (unless the buffer was too small so that the '\n' wouldn’t fit in it).

3

  • Can you please clarify the relationship/problem of “\n” and string literal? I am getting not equal result in comparing of strings (line) of a file with other whole file.

    Jul 17, 2019 at 16:32

  • @incompetent — if you read a line from a file with fgets(), then the string might be "abc\n" because fgets() keeps the newline. If you compare that with "abc", you will get ‘not equal’ because of the difference between a null byte terminating "abc" and the newline in the read data. So, you have to zap the newline. The reliable one-line way to do that is buffer[strcspn(buffer, "\n")] = '\0'; which has the merit of working correctly regardless of whether there is any data in the buffer, or whether that data ends with a newline or not. Other ways of zapping the newline easily crash.

    Jan 16, 2020 at 3:39

  • This answer addresses the issues of the code accurately, while the most upvoted and accepted answer covers only to answer the question´s title. Especially to mention the last paragraph is super. +1

    May 30, 2020 at 9:49

13

Use strcmp.

This is in string.h library, and is very popular. strcmp return 0 if the strings are equal. See this for an better explanation of what strcmp returns.

Basically, you have to do:

while (strcmp(check,input) != 0)

or

while (!strcmp(check,input))

or

while (strcmp(check,input))

You can check this, a tutorial on strcmp.

0