Robert74
Robert74

Reputation: 61

pointers and string parsing in c

I was wondering if somebody could explain me how pointers and string parsing works. I know that I can do something like the following in a loop but I still don't follow very well how it works.

  for (a = str;  * a;  a++) ...

For instance, I'm trying to get the last integer from the string. if I have a string as const char *str = "some string here 100 2000";

Using the method above, how could I parse it and get the last integer of the string (2000), knowing that the last integer (2000) may vary.

Thanks

Upvotes: 5

Views: 7360

Answers (5)

SiegeX
SiegeX

Reputation: 140397

I know this has been answered already but all the answers thus far are recreating code that is available in the Standard C Library. Here is what I would use by taking advantage of strrchr()

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

int main(void)
{

    const char* input = "some string here 100 2000";
    char* p;
    long l = 0;

    if(p = strrchr(input, ' '))
        l = strtol(p+1, NULL, 10);

    printf("%ld\n", l);

    return 0;
}

Output

2000

Upvotes: 3

Stephen
Stephen

Reputation: 49196

for (a = str; * a; a++) ...

This works by starting a pointer a at the beginning of the string, until dereferencing a is implicitly converted to false, incrementing a at each step.

Basically, you'll walk the array until you get to the NUL terminator that's at the end of your string (\0) because the NUL terminator implicitly converts to false - other characters do not.

Using the method above, how could I parse it and get the last integer of the string (2000), knowing that the last integer (2000) may vary.

You're going to want to look for the last space before the \0, then you're going to want to call a function to convert the remaining characters to an integer. See strtol.

Consider this approach:

  • find the end of the string (using that loop)
  • search backwards for a space.
  • use that to call strtol.

-

for (a = str; *a; a++);  // Find the end.
while (*a != ' ') a--;   // Move back to the space.
a++;  // Move one past the space.
int result = strtol(a, NULL, 10);

Or alternatively, just keep track of the start of the last token:

const char* start = str;
for (a = str; *a; a++) {     // Until you hit the end of the string.
  if (*a == ' ') start = a;  // New token, reassign start.
}
int result = strtol(start, NULL, 10);

This version has the benefit of not requiring a space in the string.

Upvotes: 8

mbq
mbq

Reputation: 18628

The loop you've presented just goes through all characters (string is a pointer to the array of 1-byte chars that ends with 0). For parsing you should use sscanf or better C++'s string and string stream.

Upvotes: -1

Paul R
Paul R

Reputation: 212979

You just need to implement a simple state machine with two states, e.g

#include <ctype.h>

int num = 0; // the final int value will be contained here
int state = 0; // state == 0 == not parsing int, state == 1 == parsing int

for (i = 0; i < strlen(s); ++i)
{
    if (state == 0) // if currently in state 0, i.e. not parsing int
    {
        if (isdigit(s[i])) // if we just found the first digit character of an int
        {
            num = s[i] - '0'; // discard any old int value and start accumulating new value
            state = 1; // we are now in state 1
        }
        // otherwise do nothing and remain in state 0
    }
    else // currently in state 1, i.e. parsing int
    {
        if (isdigit(s[i])) // if this is another digit character
        {
            num = num * 10 + s[i] - '0'; // continue accumulating int
            // remain in state 1...
        }
        else // no longer parsing int
        {
            state = 0; // return to state 0
        }
    }
}

Upvotes: 3

Prasoon Saurav
Prasoon Saurav

Reputation: 92864

  for (a = str;  * a;  a++)...

is equivalent to

  a=str;
  while(*a!='\0') //'\0' is NUL, don't confuse it with NULL which is a macro
  {
      ....
      a++;
  }

Upvotes: 0

Related Questions