Почему C ++ strtok () не работает для меня? - PullRequest
1 голос
/ 19 февраля 2010

Предполагается, что программа получает входные данные через cin, токенизирует их, а затем выводит каждый из них, чтобы показать мне, что он работает правильно.Это не.

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

Что я делаю не так?

int main(int argc, char* argv[])
{
  string input_line;

  while(std::cin >> input_line){
    char* pch = (char*)malloc( sizeof( char ) *(input_line.length() +1) );

    char *p = strtok(pch, " ");
    while (p != NULL) {
      printf ("Token: %s\n", p);
      p = strtok(NULL, " ");
    }
  }
  return 0;
}

Iследуйте примеру кода здесь: http://www.cplusplus.com/reference/clibrary/cstring/strtok/

Спасибо.

Ответы [ 5 ]

9 голосов
/ 19 февраля 2010

Похоже, вы забыли скопировать содержимое input_line в pch:

strcpy(pch, input_line.c_str());

Но я не уверен, почему вы все равно делаете токенизацию строк. Выполнение cin >> input_line не будет читать строку, но токен .. так вы все равно получаете токены?

5 голосов
/ 19 февраля 2010

Это скорее корректный пост, у Ганса есть ваша проблема.

Правильный способ получить строку ввода - getline:

std::string s;
std::getline(std::cin, s);

std::cin в любом случае разрывается на пробел, поэтому, если вы наберете asd 123 и запустите свой код, input_line сначала будет «asd», затем второй раз в цикле «123» (без ожидания ввода).

Тем не менее, простой способ получить ваш результат - stringstream. Каждый раз, когда вы явно выделяете память, особенно с malloc, вы, вероятно, делаете что-то нелегко. Вот одно из возможных решений для токенизации строки:

#include <sstream>
#include <string>
#include <iostream>

int main(void)
{
    std::string input;
    std::getline(std::cin, input);

    std::stringstream ss(input);
    std::string token;
    while(std::getline(ss, token, ' '))
    {
        std::cout << token << "...";
    }

    std::cout << std::endl;
}

Если вы действительно хотите использовать strtok, вы можете сделать что-то вроде этого:

#include <cstring>
#include <string>
#include <iostream>
#include <vector>

int main(void)
{
    std::string input;
    std::getline(std::cin, input);

    std::vector<char> buffer(input.begin(), input.end());
    buffer.push_back('\0');

    char* token = strtok(&buffer[0], " ");
    for (; token; token = strtok(0, " "))
    {
        std::cout << token << "...";
    }

    std::cout << std::endl;
}

Помните, что ручное управление памятью плохо. Используйте vector для массивов, и вы избежите утечек. (Какой у вас код!)

1 голос
/ 19 февраля 2010

Вы не инициализировали свою строку. Вставить

strcpy(pch, input_line.c_str());

после строки malloc.

0 голосов
/ 19 февраля 2010

GMan ответ, вероятно, лучше и более чисто с ++.Это скорее микс, который специально использует strtok(), так как я думаю, что это была ваша цель.

Я использовал strdup() / free(), так как это был самый простой способ скопировать строку.В вопросе у вас была утечка памяти, так как вы malloc() не соответствовали free().

Кроме того, оператор >> со строкой будет разбиваться на пробелах и поэтому не подходит для получения строк.Вместо этого используйте getline().

token.cpp

#include <iostream>
#include <string>
#include <cstring> /* for strtok() and strdup() */
#include <cstdlib> /* for free() */

int main(int argc, char * argv[]){
    std::string line;

    while(getline(std::cin, line)){
        char *pch = strdup(line.c_str());

        char *p = strtok(pch, " ");

        while(p){
            std::cout<<"Token: "<<p<<std::endl;
            p = strtok(NULL, " ");
        }

        std::cout <<"End of line"<<std::endl;
        free(pch);
    }
    return 0;
}

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

$ printf«Привет, мне нравятся токены \ nНа новых линиях тоже \ n \ nБлоки в порядке» | ./token
Токен: Hi
Токен: там,
Токен: I
Токен: как
Токен: токены
Конец строки
Токен: Вкл
Токен: новый
Токен: линии
Токен: тоже
Конец строки
Конец строки
Токен: Пробелы
токен:
токен: штраф
конец строки

0 голосов
/ 19 февраля 2010

Или используйте это:

pch = strdup(input_line.c_str());
...