views:

143

answers:

4

Pay attentions that there is a space in it.

Which function can I use?

+5  A: 

You can use

if (!strncmp("GET ", str, 4)
{ 
   ... 
} 
else if (!strncmp("POST ", str, 5)) 
{
   ...
} 
else
{
   ...
}
LukeN
Of course he needs strncmp. strcmp("GET ", "GET LOST") will not return 0.
bmargulies
Okay, so the amount of tested characters equal the longest string of the two? Gotta update it real fast.
LukeN
+1  A: 

Use strncmp with parameters string1, string2, n where string1 and string2 are the strings to be compared and n the number of characters. strncmp returns 0 if the strings match or <0 if string1 is lexicographically smaller than string2 or >0 if string2 is smaller than string1. Examples:

#include <string.h>
...
strncmp(somestring, "GET ", 4) == 0
strncmp(somestring, "POST ", 5) == 0
George B.
strncmp returns 0 when the inputs match.
MSN
I know, sorry forgot to write it.
George B.
+1  A: 
#include <stdio.h>
#include <string.h>

typedef enum httpmethod
{
    HTTP_ERR,
    HTTP_GET,
    HTTP_POST,
    HTTP_METHOD_COUNT

} httpmethod;

const char* http_method_str[HTTP_METHOD_COUNT + 1] =
{
    "UNKNOWN",
    "GET ",
    "POST ",
    0
};


httpmethod str_get_http_method(const char* str)
{
    if (!str || strlen(str) < 4)
        return HTTP_ERR;

    const char* ptr[HTTP_METHOD_COUNT];
    int i;
    int failcount = 0;

    for (i = 1; i < HTTP_METHOD_COUNT; ++i)
        ptr[i] = http_method_str[i];

    while (*str != '\0' && failcount < HTTP_METHOD_COUNT - 1)
    {
        for (i = 1; i < HTTP_METHOD_COUNT; ++i)
        {
            if (ptr[i] && *str != *ptr[i]++)
            {
                ptr[i] = 0;
                ++failcount;
            }
        }
        str++;
    }

    for (i = 1; i < HTTP_METHOD_COUNT; ++i)
        if (ptr[i])
            return i;

    return HTTP_ERR;
}


int main(int argc, char** argv)
{
    const char* test[4] = { "GET ", "POST ", "GIT ", "PAST " };

    httpmethod result = HTTP_ERR;

    int i;

    for (i = 0; i < 4; ++i)
    {
        printf("checking str: %s\n", test[i]);
        result = str_get_http_method(test[i]);
        printf("result is type: %s\n", http_method_str[result]);
    }

    return 0;
}
James Morris
You probably want a NULL at the end of initializing `http_method_str[]`.
Tim Post
@Tim: Well the enum tells you how many, and adding a NULL requires a further array index, but I see no harm in doing that so will :-)
James Morris
+3  A: 

You don't have to use strncmp() when you only need to differentiate between a few strings:

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

static uint32_t method_hash(const char *key)
{
        int len;
        uint32_t hash;
        int i;

        len = strlen(key);
        for (hash = 0, i = 0; i < len; i++) {
                hash += (unsigned int) key[i];
                hash += (hash << 10);
                hash ^= (hash >> 6);
        }
        hash += (hash << 3);
        hash ^= (hash >> 11);
        hash += (hash << 15);
        return hash;
}

int main(int argc, char *argv[])
{
     if (argc < 2) {
        printf("Usage: %s <method>\n", argv[0]);
        return 0;
     }

     switch(method_hash(argv[1])) {
     case 802187597:
        printf("Its GET\n");
        break;
     case 740659500:
        printf("Its POST\n");
        break;
     default:
        printf("Its RUBBISH\n");
        return 1;
     }

     return 0;
}

Just note, the hash is not collision proof, but is suitable to know the difference between GET and POST. I use that little gem in dictionaries quite often, only calling strncmp() when I think I have a match.

I'm posting this answer to tell you, there are many ways to deal with strings, in hopes that you avoid code that looks like this as you continue to learn C:

if (! strncmp(string, "FOO ", 4)) {
     do_this();
} else if (! strncmp(string, "BAR ", 4)) {
     do_that();
} else if (! strncmp(string, "FOOBAR ", 7)) {
     do_both();
 /* ... madness ensues through 200 more lines and 100 more else if's ... */
} else {
     return 0;
}

My example is not exactly proper. You'd want the hash values determined at run time instead of just plugging in the known values if you want the code to be portable. That's an exercise for the reader (hint, switch cases want constants).

Tim Post
Nice answer....
James Morris
But have you paid attention to the space?
James Morris
Just a comment on your example with a huge series of `else if (! strncmp( string...` statements. In that case, I'd think a table of strings and function pointers would be a cleaner solution. That and creating a `str_begins()` kind of function that doesn't require a length parameter.
tomlogic
@James, yes. I left _plenty_ of space for the OP to do that on their own :) But no, the unsigned hashes do not reflect a space at the end of either string.
Tim Post
@James, I _just_ noticed that yes, I did forget about them in the second example :) Thanks! Updated :)
Tim Post