Peter D
Peter D

Reputation: 47

Advance pointer and get 2 more characters after strchr in C

I'm trying to get 2 more characters after finding the first occurrence with strchr over a char pointer. The string can look like:

foo;bar;2012 -> should output foo;b
foo;caz;     -> should output foo;c
foo;         -> should output foo (there are no +2 chars)
foo          -> null

For the first case, I figure I can do something like,

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

int main ()
{
  char str[] = "foo;bar;2012";
  char *pch = NULL;

  if ((pch=strchr(str,';')) != NULL) {
    *pch++;
    *pch++;
    *pch = '\0';
  }
  puts(str);
  return 0;
}

But what's the proper way of checking if I can advance the pointer within the string without going over?

Upvotes: 2

Views: 938

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 753655

The *pch++ lines should be generating a compiler warning (if they don't, you aren't compiling with enough warnings enabled). I compile with warnings treated as errors so I get:

xw31.c:10:5: error: value computed is not used [-Werror=unused-value]
     *pch++;

You should use pch++; — that doesn't read but ignore the value.

You should check that you've not reached end of string while accessing beyond where strstr() points you, so could use:

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

int main(void)
{
    char str[] = "foo;bar;2012";
    char *pch;

    if ((pch = strchr(str, ';')) != NULL)
    {
        if (pch[1] != '\0' && pch[2] != '\0')
            pch[3] = '\0';
        puts(str);
    }
    return 0;
}

If the inner test fails, the string is short enough already. pch[0] is the semicolon, of course. This generates foo;ba as the output. If you want just foo;b, then you only need to test one character less ahead:

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

int main(void)
{
    char str[] = "foo;bar;2012";
    char *pch;

    if ((pch = strchr(str, ';')) != NULL)
    {
        if (pch[1] != '\0')
            pch[2] = '\0';
        puts(str);
    }
    return 0;
}

Upvotes: 3

Related Questions