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」で2回目(入力を待たずに)になります。

とはいえ、結果を得る簡単な方法はを使用することstringstreamです。特にメモリを明示的に割り当てるときはいつでも、mallocおそらく難しい方法で何かをしていることになります。文字列をトークン化するための1つの可能な解決策は次のとおりです。

#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;
}

手動でのメモリ管理は悪いことを忘れないでください。for配列を使用するvectorと、リークを回避できます。(あなたのコードはどれですか!)

于 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 'こんにちは、私はトークンが好きです\n改行も\n\n空白は問題ありません'|./token
トークン: こんにちは
トークン: そこに、
トークン: I
トークン: いいね
トークン: トークン
行末
トークン: オン
トークン: 新しい
トークン: 行
トークン: too
行末
行末
トークン: 空白
トークン: are
トークン: 細かい
行末

于 2010-02-19T17:28:44.690 に答える