Thread: String testing equality

  1. #1
    Registered User
    Join Date
    Oct 2019
    Posts
    82

    String testing equality

    I have a code like the below, based on another similar code from the internet. Now, this code uses the not equal operator to compare between string while, to my knowledge, 'strcmp' should be what to use but the code strangely works. Is this correct? What exactly is happening....

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    int main()
    {
            char *arr[] = {"Chair", "Stool", "Table", ""};
            char **arrptr = arr;
            while (*arrptr != "")
            {
                    printf("%s\n", *arrptr++);
            }
    
    
            return 0;
    }
    My proposed code would use strcmp and hence look like:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    int main()
    {
            char *arr[] = {"Chair", "Stool", "Table", ""};
            char **arrptr = arr;
            while (strcmp(*arrptr, "") != 0)
            {
                    printf("%s\n", *arrptr++);
            }
    
    
            return 0;
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    It's not comparing strings, it's comparing pointers.

    And it relies on the compiler combining identical strings, so that the pointer to "" in the array is the same pointer to "" in the while statement.

    Using strcmp is the way forward, especially if you're planning to say type in "Chair" at some point and hope to be able to find it in the array.
    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.

  3. #3
    Registered User
    Join Date
    Oct 2019
    Posts
    82
    Quote Originally Posted by Salem View Post
    It's not comparing strings, it's comparing pointers.

    And it relies on the compiler combining identical strings, so that the pointer to "" in the array is the same pointer to "" in the while statement.
    Didn't quite get the part about the compiler but I suppose the code should be equivalent to this:

    Code:
    #include <stdio.h>
    #include <string.h>
    
    
    int main()
    {
    	char *arr[] = {"Chair", "Stool", "Table", NULL}; 
    	char **arrptr = arr;
    	while (*arrptr != NULL)
    	{
    		printf("%s\n", *arrptr++);
    	}
    
    
    	return 0;
    }

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    As far as the compiler is concerned, a string constant is represented as an anonymous char array.

    So your first post is
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    const char anon1[] = "Chair";
    const char anon2[] = "Stool";
    const char anon3[] = "Table";
    const char anon4[] = "";
    int main()
    {
            char *arr[] = {anon1, anon2, anon3, anon4};
            char **arrptr = arr;
            while (*arrptr != anon4)
            {
                    printf("%s\n", *arrptr++);
            }
      
            return 0;
    }
    But the compiler (well a stupid one) could have done this, not realising two strings are the same.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    const char anon1[] = "Chair";
    const char anon2[] = "Stool";
    const char anon3[] = "Table";
    const char anon4[] = "";
    const char anon5[] = "";
    int main()
    {
            char *arr[] = {anon1, anon2, anon3, anon4};
            char **arrptr = arr;
            while (*arrptr != anon5)
            {
                    printf("%s\n", *arrptr++);
            }
     
            return 0;
    }
    Now the code is very broken.


    Using a NULL pointer is a much better idea.
    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.

  5. #5
    Registered User
    Join Date
    Oct 2019
    Posts
    82
    Quote Originally Posted by Salem View Post
    As far as the compiler is concerned, a string constant is represented as an anonymous char array.

    So your first post is
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    const char anon1[] = "Chair";
    const char anon2[] = "Stool";
    const char anon3[] = "Table";
    const char anon4[] = "";
    int main()
    {
            char *arr[] = {anon1, anon2, anon3, anon4};
            char **arrptr = arr;
            while (*arrptr != anon4)
            {
                    printf("%s\n", *arrptr++);
            }
      
            return 0;
    }
    But the compiler (well a stupid one) could have done this, not realising two strings are the same.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    const char anon1[] = "Chair";
    const char anon2[] = "Stool";
    const char anon3[] = "Table";
    const char anon4[] = "";
    const char anon5[] = "";
    int main()
    {
            char *arr[] = {anon1, anon2, anon3, anon4};
            char **arrptr = arr;
            while (*arrptr != anon5)
            {
                    printf("%s\n", *arrptr++);
            }
     
            return 0;
    }
    Now the code is very broken.


    Using a NULL pointer is a much better idea.
    Okay, got it now.

    What this code does is essentially to loop through an array of strings or a list of strings. This list/array does have a sentinel value at the end, though. It is possible to transverse though the array/list without a sentinel character?

    From my othe thread, after splitting the string, it is possible to transverse through it with:

    Code:
    static void concatenate(char **tokens)
    {
        while(*tokens)
        {
            printf("%s \n", *tokens++);
        }
    }
    At least it does print the strings and doesn't segmentation fault. It is not clear to me how reliable this is? For instance, trying to loop through our current example fails with a seg fault.

    Can you give some input on this?
    Last edited by ghoul; 01-15-2022 at 06:55 AM. Reason: Code edit

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Your concatenate is fine, so long as your array has a NULL sentinel value at the end.

    No sentinel, then you need to provide a count of how many elements there are.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. String equality
    By JohnAnon in forum C++ Programming
    Replies: 11
    Last Post: 03-25-2011, 11:58 PM
  2. String testing
    By Nailz in forum C Programming
    Replies: 3
    Last Post: 11-22-2009, 02:15 PM
  3. string equality testing
    By Bladactania in forum C Programming
    Replies: 2
    Last Post: 02-17-2009, 06:24 AM
  4. Test of Equality for String Macro - Invalid?
    By Jesdisciple in forum C Programming
    Replies: 28
    Last Post: 01-25-2009, 04:47 PM
  5. testing 2 strings for equality
    By Unregistered in forum C++ Programming
    Replies: 3
    Last Post: 11-12-2001, 04:55 AM

Tags for this Thread