указатели и строковый парсинг в c

Я задавался вопросом, мог ли кто-то объяснить меня, как парсинг указателей и строки работает. Я знаю, что могу сделать что-то как следующее в цикле, но я все еще не следую очень хорошо, как оно работает.

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

Например, я пытаюсь получить последнее целое число от строки. если у меня есть строка как const char *str = "some string here 100 2000";

Используя метод выше, как я мог проанализировать его и получить последнее целое число строки (2000), зная, что последнее целое число (2000) может варьироваться.

Спасибо

5
задан Robert74 27 June 2010 в 14:52
поделиться

5 ответов

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

Эта версия имеет то преимущество, что не требует пробела в строке.

8
ответ дан 18 December 2019 в 14:42
поделиться

Я знаю, что на этот вопрос уже отвечали, но все ответы до сих пор воссоздают код, который доступен в стандартной библиотеке 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;
}

Output

2000
3
ответ дан 18 December 2019 в 14:42
поделиться

Вам просто нужно реализовать простую машину состояний с двумя состояниями, например

#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
        }
    }
}
3
ответ дан 18 December 2019 в 14:42
поделиться
  for (a = str;  * a;  a++)...

эквивалентно

  a=str;
  while(*a!='\0') //'\0' is NUL, don't confuse it with NULL which is a macro
  {
      ....
      a++;
  }
0
ответ дан 18 December 2019 в 14:42
поделиться

Цикл представленный вами просто проходит через все символы (строка - это указатель на массив однобайтовых символов, который заканчивается на 0). Для синтаксического анализа вы должны использовать строку и поток строк sscanf или лучше C ++ .

-1
ответ дан 18 December 2019 в 14:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: