C++ Strtok():标记化字符串
我一直收到一个错误,上面写着“调用'strtok'时没有匹配的函数”。我不太擅长编码,我很困惑D: 我从文件中读取的行示例: Wilco Wilco 2009非此类记录11 58 RockC++ Strtok():标记化字符串,c++,C++,我一直收到一个错误,上面写着“调用'strtok'时没有匹配的函数”。我不太擅长编码,我很困惑D: 我从文件中读取的行示例: Wilco Wilco 2009非此类记录11 58 Rock int find_oldest_album(Album **& albums, int num_of_albums){ string line; ifstream fin; fin.open("/Users/ms/Desktop/albums.txt"); while
int find_oldest_album(Album **& albums, int num_of_albums){
string line;
ifstream fin;
fin.open("/Users/ms/Desktop/albums.txt");
while (!fin.eof())
{
getline(fin, line, '\n');
char * artist_name;
char artist_name = strtok(line, '\t');
char * title_name;
title_name = strtok(NULL, '\t');
char * release_year;
release_year = strtok(NULL, '\t');
}
fin.close();
}
strtok
函数只能应用于字符数组。这是一个C标准函数。如果要解析类型为std::string
的对象,请使用标准流类std::istringstream
时使用std::istringstream
的解析方法与使用strtok
的解析方法相同
比如说
#include <sstream>
//...
std::string line;
std::getline( fin, line, '\n' );
std::istringstream is( line );
std::string artist_name;
std::getline( is, artist_name, '\t' );
有三个错误。您正在重新声明名称弗拉德,函数Strtok可能不与类型<代码> STD::String 一起使用,函数第二个参数“代码> Strtok < /Calp>,分隔符必须指定为字符串,它具有类型<代码> const char */COD> < < /P> < P>用C++编写的更好的解决方案由MasCO在他的回答中概述。要解决错误“调用'strtok'没有匹配的函数”,您需要包括头文件,如下所示:
#include<cstring>
#包括
strtok
是一个已损坏的C函数,不应使用。它需要一个
可写的C字符串(不是std::string
),它具有静态
很容易被破坏
如果您的行具有标准分隔符,例如制表符,
编写一个函数将它们分解为字段很容易:
std::vector<std::string>
split( std::string const& line )
{
std::vector<std::string> results;
std::string::const_iterator end = line.end();
std::string::const_iterator current = line.start();
std::string::const_iterator next = std::find( current, end, '\t' );
while ( next != end ) {
results.push_back( std::string( current, next ) );
current = next + 1;
next = std::find( current, end, '\t' );
}
results.push_back( std::string( current, end ) );
return results;
}
std::vector
拆分(标准::字符串常量和行)
{
std::矢量结果;
std::string::const_迭代器end=line.end();
std::string::const_迭代器current=line.start();
std::string::const_iterator next=std::find(当前,结束,'\t');
while(下一步!=结束){
结果:推回(std::string(current,next));
电流=下一个+1;
next=std::find(当前,结束,'\t');
}
结果:推回(std::string(current,end));
返回结果;
}
更一般地说,对于任何解析问题,只需迭代
字符串,如上所述。实际上也可以用于标记化。这是一种可怕的方法。为什么滥用
std::getline
,而std::find
也同样有效。@詹姆斯·坎泽:这是一种非常好的方法。它使用std:;“发现”是可怕的,因为事实上什么也找不到。正在输入数据字段。如果输入包含不同类型的数据,例如数字、字符串、bool等等,那么你的方法就是错误的,这是混淆。函数名为getline
,不提前搜索。
std::vector<std::string>
split( std::string const& line )
{
std::vector<std::string> results;
std::string::const_iterator end = line.end();
std::string::const_iterator current = line.start();
std::string::const_iterator next = std::find( current, end, '\t' );
while ( next != end ) {
results.push_back( std::string( current, next ) );
current = next + 1;
next = std::find( current, end, '\t' );
}
results.push_back( std::string( current, end ) );
return results;
}