Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Strtok():标记化字符串_C++ - Fatal编程技术网

C++ Strtok():标记化字符串

C++ 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

我一直收到一个错误,上面写着“调用'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 (!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;
}