C中的指针和字符串解析

发布于 2024-09-07 01:06:06 字数 305 浏览 6 评论 0原文

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

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

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

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

谢谢

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

温柔戏命师 2024-09-14 01:06:06

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

这是通过在字符串开头启动一个指针 a 来实现的,直到取消引用 a code> 隐式转换为 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);

此版本的优点是不需要字符串中的空格。

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.

绮烟 2024-09-14 01:06:06

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

#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
        }
    }
}

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
        }
    }
}
早茶月光 2024-09-14 01:06:06

我知道这个问题已经得到解答,但迄今为止的所有答案都是重新创建标准 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

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
五里雾 2024-09-14 01:06:06
  for (a = str;  * a;  a++)...

相当于

  a=str;
  while(*a!='\0') //'\0' is NUL, don't confuse it with NULL which is a macro
  {
      ....
      a++;
  }
  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++;
  }
不一样的天空 2024-09-14 01:06:06

您提供的循环仅遍历所有字符(字符串是指向以 0 结尾的 1 字节字符数组的指针)。为了进行解析,您应该使用 sscanf 或更好的 C++ 的字符串和字符串流。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文