karafar
karafar

Reputation: 516

strcmp says seemingly identical string are not equal

I am using strcmp to compare two strings. lhs is coming from a filestream via fgets. rhs is being created generated by a for loop to be a sequence of n-1 whitespaces.


Example

#include <string.h>
#include <stdio.h>

int main() {
  size_t n = 10;
  char rhs[n];

  memset(rhs, ' ', n - 1); // Fill with spaces using memset()
  rhs[n-1] = 0; // Add NUL terminator

  printf("len=%zu\n", strlen(rhs));

  char lhs[n];

  FILE* file = fopen("test", "r");
  fgets(lhs, sizeof(lhs), file);
  printf("read=%s\n", lhs);

  return 0;
}


When using gdb, I will find that I have two strings that appear identical (I used gdb's print for this):

lhs = " "

rhs = " "

Yet, strcmp(lhs, rhs) != 0. This should return a 0 indicating that the strings are identical, but instead I get some other non-zero value.

Why aren't these strings considered equal?

Upvotes: 0

Views: 1872

Answers (2)

tadman
tadman

Reputation: 211560

Cleaned up this code to create a complete, minimal example looks like this:

#include <string.h>
#include <stdio.h>

int main() {
  size_t n = 10;
  char rhs[n];

  memset(rhs, ' ', n - 1); // Fill with spaces using memset()
  rhs[n-1] = 0; // Add NUL terminator

  printf("len=%zu\n", strlen(rhs));

  char lhs[n];

  FILE* file = fopen("test", "r");
  fgets(lhs, sizeof(lhs), file);
  printf("read=%s\n", lhs);

  return 0;
}

Where here it's important to not assign from fgets, that's a warning if you have -Wall turned on.

Upvotes: 1

Shipof123
Shipof123

Reputation: 233

The string that is entered into your buffer is not the exact same, and you neglecting to add the null terminator means that the string programs will continue reading the string into a buffer until they find a null terminator, running the following code shows us this:

size_t n = 5;
char lhs[n];
char rhs[n];
for(int i = 0; i < n-1; i++)
    rhs[i] = ' ';
for(int i = 0; rhs[i]; i++)
    printf("| %d ", rhs[i]);

Output:

| 32 | 32 | 32 | 32 | unknown values ..., could be 0, but until then still part of the array

You should think of an array as a memory address, especially when passing it to a function

You should write it like this:

for(int i = 0; i < n-1; i++)
    rhs[i] = ' ';
rhs[n-1] = '\x00'; // null terminator

Upvotes: 2

Related Questions