Разбор буфера C - выдвигать буфер за пробел, хранить слово - PullRequest
0 голосов
/ 27 августа 2009

Прошло некоторое время с тех пор, как я работал со стандартным кодом синтаксического анализа строк библиотеки C (sprintf, atoi и т. Д.).

Моя конкретная, текущая потребность заключается в следующем:

advance_buf( const char*& buf, const char* removed_chars, int size );

Он должен выдвинуть указатель buf за пределы группы пробелов и скопировать удаленные символы в removed_chars ... size предназначен для обеспечения безопасности.

Пример до и после, состояние buf и removed_chars:

  • До: buf: "123 456 789", removed_chars: (пусто или мусор).
  • После: buf: "456 789", removed_chars: "123".

Меня также интересует краткий ресурс для функций такого рода.

Ответы [ 4 ]

1 голос
/ 27 августа 2009

Как насчет:

#define SPACE " \t"

const char *advance_buf(const char *buf, char *removed_chars, int size)
{
    buf += sprintf(removed_chars, "%.*s", min(size - 1, strcspn(buf, SPACE)), buf);
    return buf + strspn(buf, SPACE);
}

Примечание: если заполнится removed_chars, лишние символы не будут удалены из buf.

const char *buf = "123 456789 X"
char removed_chars[5];

// Before: buf: "123 456789 X", removed_chars: (empty).
buf = advance_buf(buf, removed_chars, sizeof (removed_chars));
// After: buf: "456789 X", removed_chars: "123".
buf = advance_buf(buf, removed_chars, sizeof (removed_chars));
// After: buf: "89 X", removed_chars: "4567".

Примечание 2. Хотя вызов sprintf безопасен, поскольку "%.*s" защищает от переполнения буфера, некоторые современные компиляторы генерируют предупреждения для любого использования sprintf(), а некоторые стандарты кодирования компании запрещают его. Если так, то это должно быть тривиально заменить snprintf или sprintf_s.

1 голос
/ 27 августа 2009

Это должно быть тривиально:

const char * advance_buf(const char *buf, char *removed_chars, size_t size)
{
  /* Copy characters until whitespace found or buffer space runs out. */
  while(!isspace(*buf) && --size > 0)
    *removed_chars++ = *buf++;
  *removed_chars = '\0';

  /* Remove separating whitespace. */
  while(isspace(*buf))
    buf++;
  return buf;
}

Я немного изменил подпись, чтобы вернуть обновленный указатель buf.

1 голос
/ 27 августа 2009

Похоже, strtok () , и друзья могут делать то, что вы хотите.

0 голосов
/ 27 августа 2009

Я бы порекомендовал взглянуть на функции strspn() и strcspn(). Следующий код расскажет вам, сколько символов существует до следующего фрагмента пробела:

strcspn(string, " \t");

И следующее скажет вам, как долго будет пустое пространство:

strspn(string, " \t");

Вы можете использовать эти числа для выполнения этой задачи довольно легко и, возможно, поточно-ориентированно, если вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...