5

我想知道是否有人可以向我解释指针和字符串解析的工作原理。我知道我可以循环执行以下操作,但我仍然不太了解它是如何工作的。

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

例如,我试图从字符串中获取最后一个整数。如果我有一个字符串const char *str = "some string here 100 2000";

使用上面的方法,我如何解析它并获取字符串的最后一个整数(2000),知道最后一个整数(2000)可能会有所不同。

谢谢

4

5 回答 5

8

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

这通过a在字符串的开头开始一个指针来工作,直到取消引用a被隐式转换为 false,a每一步递增。

基本上,您将遍历数组,直到到达字符串末尾的 NUL 终止符 ( \0),因为 NUL 终止符隐式转换为 false - 其他字符不会。

使用上面的方法,我如何解析它并获取字符串的最后一个整数(2000),知道最后一个整数(2000)可能会有所不同。

您将要查找 之前的最后一个空格\0,然后您将要调用一个函数将剩余的字符转换为整数。见strtol

考虑这种方法:

  • 找到字符串的结尾(使用那个循环)
  • 向后搜索空格。
  • 用它来调用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);

或者,只需跟踪最后一个标记的开始:

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);

此版本的好处是字符串中不需要空格。

于 2010-06-27T14:57:15.010 回答
3

您只需要实现一个具有两种状态的简单状态机,例如

#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
        }
    }
}
于 2010-06-27T15:01:08.433 回答
3

我知道这已经得到了回答,但到目前为止所有的答案都是重新创建标准 C 库中可用的代码。这是我将利用的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;
}

输出

2000
于 2010-06-27T21:58:15.997 回答
0
  for (a = str;  * a;  a++)...

相当于

  a=str;
  while(*a!='\0') //'\0' is NUL, don't confuse it with NULL which is a macro
  {
      ....
      a++;
  }
于 2010-06-27T14:58:09.233 回答
-1

您提供的循环只遍历所有字符(字符串是指向以 0 结尾的 1 字节字符数组的指针)。对于解析,您应该使用sscanfor betterC++的字符串和字符串流。

于 2010-06-27T14:56:40.173 回答