斯特托克和夏尔*

Strtok and Char*

本文关键字:夏尔      更新时间:2023-10-16

我有一个简单的代码,我试图通过一个char*并将其吐到单独的单词中。 这是我拥有的简单代码。

#include <iostream>
#include <stdio.h>
int main ()
{
   char * string1 = "- This is a test string";
   char * character_pointer;
   std::cout << "Splitting stringinto tokens:" << string1 << std::endl;
   character_pointer = strtok (string1," ");
   while (character_pointer != NULL)
   {
       printf ("%sn", character_pointer);
       character_pointer = strtok (NULL, " ");
   }
   return 0;
}

收到一个错误,不允许我这样做。

所以我的问题是,我如何通过并找到char*中的每个单词。 对于我正在处理的实际程序,我的一个库返回一段单词作为const char*,我需要使用词干提取算法对每个单词进行词干提取(我知道该怎么做,我只是不知道如何将每个单独的单词发送到词干分析器(。 如果有人能解决如何让示例代码工作,我将能够弄清楚。 所有在线示例都使用char[]表示string1而不是char*,我不能这样做。

这是我所知道的在 c++ 中拆分字符串的最简单(代码(方法:

std::string string1 = "- This is a test string";
std::string word;
std::istringstream iss(string1);
// by default this splits on any whitespace
while(iss >> word) {
    std::cout << word << 'n';
}

或者像这样,如果你想指定一个分隔符。

while(std::getline(iss, word, ' ')) {
    std::cout << word << 'n';
}

这是一个更正的版本,请尝试一下:

#include <iostream>
#include <stdio.h>
#include <cstring>
int main ()
{
   char string1[] = "- This is a test string";
   char * character_pointer;
   std::cout << "Splitting stringinto tokens:" << string1 << std::endl;
   character_pointer = strtok (string1," ");
   while (character_pointer != NULL)
   {
       printf ("%sn", character_pointer);
       character_pointer = strtok (NULL, " ");
   }
   return 0;
}

在C++中有不同的方法可以做到这一点。

如果空格是分隔的,那么您可以通过以下方式获取令牌:

std::string text = "- This is a test string";
std::istringstream ss(text);
std::vector<std::string> tokens;
std::copy(std::istream_iterator<std::string>(ss),
          std::istream_iterator<std::string>(),
          std::back_inserter<std::vector<std::string>>(tokens));

您还可以使用正则表达式在C++中标记字符串。

std::string text = "- This is a test string";
std::regex pattern("\s+");
std::sregex_token_iterator it(std::begin(text), std::end(text), pattern, -1);
std::sregex_token_iterator end;
for(; it != end; ++it)
{
   std::cout << it->str() << std::endl;
}

忘掉strtok . 为了得到你看起来的样子目标:

std::string const source = "- This is a test string";
std::vector<std::string> tokens;
std::string::const_iterator start = source.begin();
std::string::const_iterator end   = source.end();
std::string::const_iterator next  = std::find( start, end, ' ' );
while ( next != end ) {
    tokens.push_back( std::string( start, next ) );
    start = next + 1;
    next = std::find( start, end, ' ' );
}
tokens.push_back( std::string( start, next ) );

当然,这可以根据需要进行修改:您可以使用 std::find_first_of您想要多个分隔符,或者 std::search是否想要多字符分隔符,甚至 std::find_if用于任意测试(使用 lambda,如果您有C++11(. 在大多数解析的情况下,您可以只需传递两个迭代器,而不必构造子字符串;你只需要构造一个子字符串,当你想要将提取的令牌保存在某处。

一旦你习惯了使用迭代器和标准算法,你会发现它比strtok灵活多了,而且它没有内部的所有缺点状态暗示。