1

该程序应该通过 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;
}

我在这里遵循了代码示例:http ://www.cplusplus.com/reference/clibrary/cstring/strtok/

谢谢。

4

5 回答 5

9

看起来您忘记将内容复制input_line到 pch:

strcpy(pch, input_line.c_str());

但我不确定你为什么要进行字符串标记化。这样做cin >> input_line不会读取一行,而是一个令牌..所以无论如何你都会得到令牌?

于 2010-02-19T16:58:22.430 回答
5

这更像是一个正确的帖子,汉斯有你的问题。

获取一行输入的正确方法是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;
}

请记住,手动内存管理是不好的。使用 a vectorfor 数组,可以避免泄漏。(你的代码有!)

于 2010-02-19T17:10:46.793 回答
1

你没有初始化你的字符串。插入

strcpy(pch, input_line.c_str());

行后malloc

于 2010-02-19T17:01:27.047 回答
0

或者使用这个:

pch = strdup(input_line.c_str());
于 2010-02-19T17:04:52.533 回答
0

GMan 的答案可能更好,更纯粹是 c++。这更像是一种专门使用的组合strtok(),因为我认为这是你的目标。

我使用strdup()/free()因为它是复制字符串的最简单方法。在问题中,您正在泄漏内存,因为您malloc()没有匹配free().

带有字符串的 operator>> 也会在空格处中断,因此不适合获取行。改为使用getline()

令牌.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 'Hi there, I like tokens\nOn new line too\n\nBlanks are fine'|./token
Token: Hi
Token: there,
Token: I
Token: like
Token: tokens
End of line
Token: On
Token: new
记号:lines
记号:too
End of line
End of line
记号:Blanks
记号:are
记号:fine
End of line

于 2010-02-19T17:28:44.690 回答