0

I am on a low level embedded system comparing a fixed size buffer of chars to a simple string. The buffer is much larger than the string so I think that that is why the comparison operators says that the two are not equal. This prompted me to write a simple function to compare the string to the beginning of the buffer - is this an elegant solution? Thanks

int CompareString(const char* string, int strlen)
{
     //first check to see if the length is the same
     //if there is a null char at string length then
     //they are equal
     if(MsgBuffer[strlen] != '\0')
     {
         return 0; //they are not equal
     }

     strlen = strlen - 1;

     while(strlen > -1)
     {
         if(string[strlen] != MsgBuffer[strlen])
         {
              return 0; //they are equal
         }

         strlen = strlen - 1;
     }

     return 1; //they are equal
}
5
  • 1
    Aside from what's wrong with using strncmp(); given that MsgBuffer is a global, then no it is not elegant. Commented May 27, 2011 at 6:14
  • Mitch this is single purpose low level embedded system; globals are acceptable. Commented May 27, 2011 at 6:26
  • Additionally, I am under very small space constraints - wouldn't importing string.h give me loads of un-needed bloat? Commented May 27, 2011 at 6:28
  • To the strncmp crowd: the OP clearly stated this is for an embedded system. In case the OP is a professional programmer, they will be using a static code analyzer on all of their code, to verify it. Running static code analysis on the whole of string.h is very inconvenient. So please, if you have no experience from professional programming in embedded systems, don't dismiss the question that easily. Alternatively, the OP could also be a beginner trying to figure out the inner workings of string handling functions, which is very healthy practice for beginners. Commented May 27, 2011 at 6:28
  • Importing string.h shouldn't affect the program, neither in terms of space nor namespace clutter, as you really shouldn't be using C standard function names for your own functions anyway. It will however make it a pain to test and verify the code. Commented May 27, 2011 at 6:44

4 Answers 4

3

Normally, you could look into using strncmp with the maximum length being the fixed buffer size.

But it may be that you're constrained there somewhat, especially given that you're operating in an embedded environment. It may also not be suitable for comparing space-padded strings where each string has a different number of spaces at the end (including none for a string like "formaldehyde") - strncmp won't work well for comparing "Hello" and {'H','e','l','l','o',' ',' ',' '} if the size is 8.

If that's the case, I'd be looking at something like the following:

#include <stdio.h>

int compStr (char *s1, char *s2, size_t sz) {
    while (sz != 0) {
        // At end of both strings, equal.
        if ((*s1 == '\0') && (*s2 == '\0')) break;

        // Treat spaces at end and end-string the same.
        if ((*s1 == '\0') && (*s2 == ' ')) { s2++; sz--; continue; }
        if ((*s1 == ' ') && (*s2 == '\0')) { s1++; sz--; continue; }

        // Detect difference otherwise.
        if (*s1 != *s2) return 0;

        s1++; s2++; sz--;
    }
    return 1;
}

int main (void) {
    printf ("%d\n", compStr ("Hello", "Hello", 5));
    printf ("%d\n", compStr ("Hello", "Hello     ", 5));
    printf ("%d\n", compStr ("Hello     ", "Hello", 5));
    printf ("%d\n", compStr ("Hello     ", "Hello ", 5));
    printf ("%d\n", compStr ("HelloX", "Hello", 5));
    printf ("%d\n", compStr ("HelloX", "HelloY", 5));
    printf ("%d\n", compStr ("HelloX", "HelloY", 6));
    return 0;
}

This will match strings with any number of spaces at the end, up to a specific size and has the advantage that you can pass arbitrary buffers to it rather than assuming one is a global area.


As an aside, it's not a good idea to use a standard library function like strlen as a variable name since you may want to. at some point, use the standard library.

Sign up to request clarification or add additional context in comments.

4 Comments

If the beginning of the buffer contains a string and the end may perhaps contain raw data. In that case strncmp with the buffer length won't work.
@Lundin, no, but I'm assuming the buffer is completely filled otherwise there's no way to tell where the data stops and the rubbish starts (other than the user specifying a lesser length).
We would have to assume that the string is null-terminated, or it wouldn't really be a string by C language definitions. This is why my own answer suggested strcmp and not strncmp.
@Lundin, OP has stated one of the "strings" is a fixed size buffer (ie. probably not a string). strcmp won't cut that since it's not null-terminated. Nor will strncmp with a limit of the buffer size since the buffer will probably end in spaces. If the intent is to just check the start of the buffer against the string, use strncmp with the limit being the length of the string. If the intent is to treat spaces at the end of the buffer as end of string, you'll need something like the code here.
1

Here is some code you can use. Simply pass the comparison string and the buffer as two parameters. This code should also be fully compliant with MISRA-C:2004.

sint8 gpfunc_strcmp (const uint8* s1, const uint8* s2)
{

  while ((*s1 != '\0') && (*s2 != '\0'))
  {
    if (*s1 != *s2)
    {
      break;
    }
    else
    {
      s1++; 
      s2++;
    }
  }

  return (sint8)(*s1 - *s2);
}

Comments

1

Use strncmp

Comments

0

"The comparison operators"? Do you mean == and so on? You can't use those to compare strings, since they will compare the locations, not the contents. You must use strcmp or strncmp instead.

(And I guess the answer to your actual question is that no, this is not an elegant solution, since strncmp already exists. But, as others have said, your embedded environment might make use of the strings library inconvenient.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.