Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Разбиение на лексемы


Автор: Berkut 27.2.2005, 14:34
Есть две строки string 2, string3; Надо разбить их на лексемы и сравнить попарно.

Код


char seps2[]="\n";

char *token2, *token3;

token2 = strtok(string2,seps2);
token3 = strtok(string3,seps2);

while(token2!=NULL||token3!=NULL)
{

if(strcmp(token2,token3)!=0)printf("ERROR\n");else printf(" OK\n");
token2=strtok(NULL,seps2);
token3=strtok(NULL,seps2);
}



Так вот, работает это не так как хотелось бы, если здесь ошибка?

Автор: En_t_end 27.2.2005, 15:03
char seps2[]="\n";
ИМХО сделай так : char seps2 = '\n'; - помоему \n определяется как одиночный символ.
Но это так smile просто подметил...

Добавлено @ 15:07
token2 = strtok(string2,seps2);
Ну точно smile ты передаешь аргумент-массив, и делаешь это категориски неправильно smile, изменяй
Добавлено @ 15:10
И каким образом у тебя string2 и 3 обьявлены ?

Автор: Berkut 27.2.2005, 15:13
Убрал массив, работает все равно не так.

char string2[255];
char string3[255];

Автор: En_t_end 27.2.2005, 15:15
strtok() - какие у неё типы аргументов ?

Автор: Berkut 27.2.2005, 15:15
Проблема в этом:
string1:
abc
abc2
abc3

string2:
qwe
qwe2
qwe3

Результат:

abc-qwe
и дальше строк из string 1 нету
Добавлено @ 15:16
char *strtok(char* s1,const *s2)

Автор: En_t_end 27.2.2005, 15:19
char *strtok(char* s1,const *s2)
Ну дык и подставляй указатели, функция требует не значение, а адрес имхо.
Добавлено @ 15:26
while((token2!=NULL)||(token3!=NULL))

Автор: En_t_end 27.2.2005, 15:29
Ладно забыли smile
Мне показалось, что неправильно работают аргументы с указателями, сам сейчас с этим мучаюсь smile

Автор: Chaos A.D. 1.3.2005, 03:44
Единственная проблема в том, что strtok обрабатывает одну строку, пока она не кончится. Если-бы ты отдебажил свой код, увидел бы, что для твоего примера первая лексема станет равна abc, как и надо; вторая qwe. Вроде все тоже нормально. Далее qwe2 и qwe3. И все. а дальше возвращается NULL и условие не выполняется. Если почитать описание strtok, то можно увидеть, что если первый параметр = NULL, то читается лексема из последней используемой строки. Не знаю, как функция это делает. Может буферизирует строку (глупо!), или сохраняет статический указатель на последнюю используемую строку(вераятнее всего). Вобщем, если ты строки читаешь из файла или еще откуда - то сначала прочитай все лексемы строки string2 в один массив, а потом сравнивай с теми, что будешь читать из второй строки. Но тут много минусов - дополнительные расходы памяти, необходимость в динамическом массиве. При всем уважении к тебе и твоим знаниям, я бы лично никогда не стал писать подобный код в таком стиле, и не посоветовал тебе. Но раз уж надо... Вот тебе пример еще одного варианта реализации твоей задачи только с использованием встроенных возможностей С. Без массивов, без всяких контейнеров и прочей... кхм.

Код

   char *seps = "\n";
   char *token1, *token2;
   ptrdiff_t disp1 = 0, disp2 = 0;
   token1 = strtok(string1+disp1,seps);
   disp1  += ( token1 ) ? strlen(token1)+1 : 0;
   token2 = strtok(string2+disp2,seps);
   disp2  += ( token2 ) ? strlen(token2)+1 : 0;
   while( token1 || token2 )
   {
       if ( !token1 || !token2 ) printf("ERROR\n");
       else printf( ( strcmp(token1,token2) ) ? "ERROR\n" : "OK\n" );

       token1  = ( token1 ) ? strtok(string1+disp1,seps) : NULL;
       disp1  += ( token1 ) ? strlen(token1)+1 : 0;
       token2  = ( token2 ) ? strtok(string2+disp2,seps) : NULL;
       disp2  += ( token2 ) ? strlen(token2)+1 : 0;
   }

disp1, disp2 - это у нас типа смещение от начала массива символов.
Если одна из строк пустая - прога будет жить. И будет корректно сравнивать все, что ей подсунешь. Против strtok ничего не имею, но повторюсь - ИМХО это _очень_ убогий способ выдирания лексем. Лучше никому не показывать его в качестве демонстрации своего програмистского мастерства, и сразу в топку.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)