-2

Got a small problem with C. Restricting myself to simple C (i.e. OS instructions), and two strings seem to not be the same. Here is my code:

    char inputData[256];
    int rid;
    rid = read(0,inputData,256);
    // Strip input
    char command[rid];
    int i;
    for (i = 0; i<=rid-2; i++) {
        command[i] = inputData[i];
    }
    command[rid-1] = '\0';
    if (command == "exit") {
        write(1,"exit",sizeof("exit"));
    }

Now, if a user enters "exit" into the terminal when queried and hits enter, the if for detecting "exit" never gets run. Any ideas?

Thanks,

EDIT: I am commiting to git as I go, so the current version can be found at github.com/samheather/octo-os. It's very obviously not complete code, but it demonstrates the problem.

Sam Heather
  • 1,493
  • 3
  • 19
  • 42
  • 1
    Why's everyone downvoting my question? It may be obvious to you guys, but this stuff is a bit new to me at this low level and the question is not worded badly, nor is it easy to find the answer online about pointers to char arrays (believe me, I tried - google throws up all kinds of other stuff with the same keywords). – Sam Heather Oct 16 '13 at 16:02
  • @TimCooper, possibly, I wasn't even thinking of this bug, but not completely as there's the pointer issue in this as well. – Sam Heather Oct 16 '13 at 16:03

5 Answers5

6

You can't compare strings with ==. You need to use strcmp.

if (strcmp(command, "exit") == 0) {

C strings are actually character arrays. You can think of "command" as a pointer to the first character. You want to compare every character in the string, not just the location of the first characters.

PherricOxide
  • 15,493
  • 3
  • 28
  • 41
2

You should use strcmp to compare strings in C.

if(strcmp(command, "exit") == 0) //strcmp returns 0 if strings are equal

To quote:

A zero value indicates that both strings are equal. A value greater than zero indicates
that the first character that does not match has a greater value in str1 than in str2.
a value less than zero indicates the opposite.
digital_revenant
  • 3,274
  • 1
  • 15
  • 24
2

As it stands right now, you're comparing the address of command with the address of the string literal "exit", which pretty much can't be the same.

You want to compare the contents, with either strcmp, or (if "only OS instructions" means no standard library functions) an equivalent you write yourself that walks through the strings and compares characters they contain.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • This is something I wasn't certain of from reading the passage in my book - when I create an array of chars (say, called 'myArray'), myArray is just a pointer to the first char? Or have I got that mixed up? Which part is the pointer? – Sam Heather Oct 16 '13 at 16:00
  • @SamHeather: Yes and no. `myArray` is an array, *but* in most situations, the name of an array will "decay" to the address of the first element of the array. The exceptions are when you use `sizeof(array)` or `&array`. – Jerry Coffin Oct 16 '13 at 16:02
  • 1
    So, when it decays to the first item, and I do myArray[2], it knows to shift 2*sizeof(myArray[0]) further along in memory? Doesn't that mean the length of the string is not stored, it's just however far you go until you reach the \0 ? – Sam Heather Oct 16 '13 at 16:07
  • 1
    @SamHeather: Yes -- correct on both counts. – Jerry Coffin Oct 16 '13 at 16:20
  • @SamHeather The length on the string is available - but only at the level where you have access to `myArray`: there you can use `sizeof myArray`. If you subtract 1 (the space used by the NUL terminator), you have the length. And if you have an array containing arbitrary data, you'll have to pass the length along with the data to called functions, because the caller needs to know the length. If you have a string, which has no NUL byte in the middle, this length information can be omitted, because the callee can obtain it himself via `strlen()`. – glglgl Oct 16 '13 at 16:37
  • @glglgl: That's true *only* if `myArray` is an array of char initialized from a string literal without specifying a size, as in: `char myArray[] = "whatever";` – Jerry Coffin Oct 16 '13 at 16:45
  • @JerryCoffin If I specify a size, I get the full length of the array if the size given was too short (then I'm probably lacking a NUL terminator). If the size given was too long, you are right; then the sting is probably shorter. But then I can view it as a reasonable use case of the "arbitrary, binary data" case. And if the fiven size is absolutely correct, then my claim as well is true. – glglgl Oct 16 '13 at 16:48
1

Use strcmp from the standard library.

tier1
  • 6,303
  • 6
  • 44
  • 75
1

As others said, == doesn't work with strings. The reason is that it would compare the pointers given.

In the expression

command == "exit"

command is a pointer to your array variable, while "exit" is a pointer to that string which resides in read-only data space. They can never be identical, so the comparison always is false.

That's why strcmp() is the way to go.

glglgl
  • 89,107
  • 13
  • 149
  • 217