0

If my array is :

char* String_Buffer = "Hi my name is <&1> and i have <&2> years old."
char* pos = strpbrk(String_buffer, "<");

Now pos is :

" <&1> and i have <&2> years old. "

But i need "Hi my name is". How can do this?

Sark
  • 132
  • 1
  • 4
  • 12

2 Answers2

3

First, make sure that the string you are working with is in modifiable memory1:

char String_Buffer[] = "Hi my name is <&1> and i have <&2> years old."

then, cut your string at the position where you found <:

char* pos = strpbrk(String_buffer, "<");
if(pos!=NULL)
{
    /* changing the '<' you found to the null character you are actually
     * cutting the string in that place */
    *pos=0;
}

Printing String_Buffer will now output Hi my name is. If you don't want the final space, just move pos backward of one element (being careful not to go before the beginning of String_Buffer).


  1. In your code you declared a char pointer and made it point to a string literal, which is non-modifiable (that's why you normally write const char * str = "asdasads";; in this case, instead, we are initializing a local char array, which we can change as much as we want.
Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • 1
    Adding the string terminator where you want to cut it, as shown in my example. – Matteo Italia Aug 09 '12 at 16:47
  • @user1558736 C strings are '\0'-terminated. That means that the character `0` means "the string ends here". If I have "abcdef" and replace "c" by "\0", I get the string "ab". That's what he is doing with `*pos = 0;` – luiscubal Aug 09 '12 at 16:47
  • Yes , but if String_Buffer is a long text , and now i need for example: "and i have"... How can know the position? – Sark Aug 09 '12 at 16:49
  • 1
    You can iterate this process starting from one character after the position of the last match (skipping all the characters before the first `>`), but maybe this could be done more easily with `strtok`. – Matteo Italia Aug 09 '12 at 16:50
2

If you track start separately, you can "cut out" a section of the buffer:

char *start = String_Buffer;
char *end = strpbrk(String_Buffer, "<");

if (end) {
    /* found it, allocate enough space for it and NUL */
    char *match = malloc(end - start + 1);

    /* copy and NUL terminate */
    strncpy(match, start, end - start);
    match[end - start] = '\0';

    printf("Previous tokens: %s\n", match);
    free(match);
} else {
    /* no match */
}

To walk the buffer printing each token, you'll simply hoist this into a loop:

char *start = String_Buffer, *end, *match;

while (start) {
    end = strpbrk(start, "<");
    if (!end) {
        printf("Last tokens: %s\n", start);
        break;
    } else if (end - start) {
        match = malloc(end - start + 1);

        /* copy and NUL terminate */
        strncpy(match, start, end - start);
        match[end - start] = '\0';

        printf("Tokens: %s\n", match);
        free(match);

        end++; /* walk past < */
    }

    /* Walk to > */
    start = strpbrk(end, ">");
    if (start) {
        match = malloc(start - end + 1); /* start > end */
        strncpy(match, end, start - end);
        match[start - end] = '\0';

        printf("Bracketed expression: %s\n", match);
        free(match);
        start++; /* walk past > */
    }
}
user7116
  • 63,008
  • 17
  • 141
  • 172