psychosys
psychosys

Reputation: 67

How could I compare a "substring" of a character array with another character array?

I am writing a program where I need to check if an object matches a certain type. The way it's written so far, you need to compare the character-array of the object with the character-array of the category you are looking for.

I am using strcmp to do this, for the following code let's say that Object->Name returns a character-array equal to "TypeA" ...

char type[] = "TypeA";
if (0 == strcmp (Object->Name, type))
{
    printf("Match!");
}

^This has worked well so far...

The only problem is that sometimes the character-array from Object->Name will have a 9 letter name in front of it. So Object->Name could be: "Chocolate_TypeA" or "FireTruck_TypeA"

I need to compare the last five characters with the value of type. I'm not sure how to do it.

My first idea was to use strncmp and specifying an index

char type[] = "TypeA";
if (0 == strncmp (type, Object->Name + 10))
{
    printf("Match!");
}

This works if the program only receives 15 character character-arrays (such as "Firetruck_TypeA"), but it doesn't... if Object->Name gives "TypeA" then I get a segmentation fault.

What is an easy way to grab the last 5 characters of any character-array and compare them to type?

Upvotes: 1

Views: 605

Answers (2)

user3121023
user3121023

Reputation: 8308

If you want to find a matching sub-string at the end of a string, you could work from the end of the string and compare them.
Another approach is to use strstr to find the matching sub-string. If the sub-string is found, another test is needed to see if it is at the end.

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

int revcmp ( char *check, char *find) {
    char *chk = check + strlen ( check);
    char *fnd = find + strlen ( find);

    while ( *fnd == *chk) {
        if ( fnd > find) {
            --fnd;
        }
        else {
            return 0;
        }
        if ( chk > check) {
            --chk;
        }
        else {
            break;
        }
    }
    return *fnd - *chk;
}

int main ( void) {
    char *text = "abcdefghijk";
    char *str = "fghijk";
    char *found = NULL;

    if ( revcmp ( text, str)) {
        printf ( "not found\n");
    }
    else {
        printf ( "found\n");
    }



    if ( NULL == ( found = strstr ( text, str))) {
        printf ( "not found\n");
    }
    else {
        if ( *(found + strlen ( str))) {
            printf ( "not at end\n");
        }
        else {
            printf ( "found\n");
        }
    }

    return 0;
}

Upvotes: 1

Chris
Chris

Reputation: 36660

A char array is just a bunch of bytes in a row in memory. A string is a char array terminated by '\0'.

char *foo = "hello world";
 foo                                  foo + strlen(foo)
  |                                           |
  v                                           v
+---+---+---+---+---+---+---+---+---+---+---+---+
| h | e | l | l | o |   | w | o | r | l | d | \0|
+---+---+---+---+---+---+---+---+---+---+---+---+

If you want the last five digits, you just need to do some pointer arithmetic:

 foo            foo + strlen(foo) - 5  foo + strlen(foo)
  |                       |                    |
  v                       v                    v
+---+---+---+---+---+---+---+---+---+---+---+---+
| h | e | l | l | o |   | w | o | r | l | d | \0|
+---+---+---+---+---+---+---+---+---+---+---+---+

If you pass this starting point to a function like strcmp that handles strings, it doesn't see the "hello " part. It just considers the pointer it's passed on until '\0'.

Now, what if you want to compare the 2nd character through the 5th character of "hello world"? You couldn't count on this, because there's no null terminator after 'o'. But you could use strncmp which lets you specify how many characters to compare.

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

int main(void) {
    char *foo = "hello world";

    if (strncmp(foo+1, "ello", 4) == 0) {
        printf("Matched\n");
    } 

    return 0;
}

Upvotes: 1

Related Questions