Разбор строки с переменным количеством пробельных символов в C - PullRequest
0 голосов
/ 02 июня 2011

Я довольно новичок в C и пытаюсь написать функцию, которая будет анализировать строку, такую ​​как:

"Это (5 пробелов здесь) равно (1 пробел здесь) a (2 пробела здесь) string. "

В заголовке функции будет указатель на строку, переданную в виде:

bool Class::Parse( unsigned char* string )

В конце я хотел бы проанализировать каждое слово независимо от количества пробелов между словами и сохранить слова в динамическом массиве.

Прости глупые вопросы ... НоЧто было бы наиболее эффективным способом сделать это, если я перебираю каждый символ?Это как строки хранятся?Поэтому, если бы я начал итерацию с:

while ( (*string) != '\0' ) {

--print *string here--

}

Будет ли это выводить на печать

T
h
i... etc?

Большое спасибо за любую помощь, которую вы можете предоставить.

Ответы [ 3 ]

1 голос
/ 02 июня 2011

из http://www.cplusplus.com/reference/clibrary/cstring/strtok/

/* strtok example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] ="- This, a sample string.";
  char * pch;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str," ,.-"); /* split the string on these delimiters into "tokens" */
  while (pch != NULL)
  {
    printf ("%s\n",pch);
    pch = strtok (NULL, " ,.-"); /* split the string on these delimiters into "tokens" */
  }
  return 0;
}

Разделение строки "- Это образец строки."в токены:

This 
a 
sample 
string 
0 голосов
/ 03 июня 2011

Я бы не стал выполнять нетривиальный синтаксический анализ в C, он слишком трудоемкий, язык для этого не подходит. Но если вы имеете в виду C ++ и похоже, что вы это делаете, поскольку вы написали Class :: Parse, то написание синтаксических анализаторов с рекурсивным спуском довольно легко, и вам не нужно изобретать велосипед. Например, вы можете взять Spirit или AX, если ваш компилятор поддерживает C ++ 0x. Например, ваш анализатор в AX может быть записан в несколько строк:

// assuming you have 0-terminated string
bool Class::Parse(const char* str)
{
    auto space = r_lit(' ');
    auto string_rule = "This" & r_many(space, 5) & space & 'a' & r_many(space, 2) 
        & "string" & r_end();
    return string_rule(str, str + strlen(str)).matched;
}
0 голосов
/ 02 июня 2011

Прежде всего, C не имеет классов, поэтому в программе на C вы, вероятно, определите свою функцию с помощью прототипа, более похожего на один из следующих:

char ** my_prog_parse(char * string) { 
/* (returns a malloc'd array of pointers into the original string, which has had
 * \0 added throughout ) */
char ** my_prog_parse(const char * string) {
/* (returns a malloc'd NULL-terminated array of pointers to malloc'd strings) */
void my_prog_parse(const char * string, char buf, size_t bufsiz,
                      char ** strings, size_t nstrings)
/* builds a NULL-terminated array of pointers into buf, all memory 
   provided by caller) */

Однако в C ++ вполне возможно использовать строки в стиле C ... ... 1004 *

Вы можете написать свой цикл как

while (*string) { ... ; string++; }

и он будет скомпилирован точно таким же ассемблером на современном оптимизирующем компиляторе. да, это правильный способ перебора строки в стиле C.

Посмотрите на функции strtok, strchr, strstr и strspn ... одна из них может помочь вам найти решение.

...