【问题标题】:Strtok in C++ abnormal behaviourC++异常行为中的Strtok
【发布时间】:2016-10-30 19:06:26
【问题描述】:

我正在尝试在 C++ 中使用 strtok 来获取字符串的标记。但是,我看到在 5 次运行中,函数返回的令牌不正确。有人可以请建议可能是什么问题吗?

重现我面临的问题的示例代码:

#include<iostream>
#include<vector>
#include<cstring>

using namespace std;
#define DEBUG(x) cout<<x<<endl;


void split(const string &s, const char* delim, vector<string> & v)
{
        DEBUG("Input string to split:"<<s);

        // to avoid modifying original string first duplicate the original string and return a char pointer then free the memory
        char * dup = strdup(s.c_str());
        DEBUG("dup is:"<<dup);
        int i=0;
        char* token = strtok(dup,delim);

        while(token != NULL)
        {
                DEBUG("token is:"<<string(token));
                v.push_back(string(token));
                // the call is treated as a subsequent calls to strtok:
                // the function continues from where it left in previous invocation
                token = strtok(NULL,delim);
        }
        free(dup);
}

int main()
{
        string a ="MOVC R1,R1,#434";

        vector<string> tokens;
        char delims[] = {' ',','};
        split(a,delims,tokens);
        return 0;
}

样本输出:

mayank@Mayank:~/Documents/practice$ ./a.out 
Input string to split:MOVC R1,R1,#434
dup is:MOVC R1,R1,#434
token is:MOVC
token is:R1
token is:R1
token is:#434

mayank@Mayank:~/Documents/practice$ ./a.out 
Input string to split:MOVC R1,R1,#434
dup is:MOVC R1,R1,#434
token is:MO
token is:C
token is:R1
token is:R1
token is:#434

正如您在第二次运行中看到的那样,创建的令牌是 MO C R1 R1 #434 而不是 MOVC R1 R1 #434

我也尝试检查库代码,但无法找出错误。请帮忙。

EDIT1:我的 gcc 版本是:gcc version 6.2.0 20161005 (Ubuntu 6.2.0-5ubuntu12)

【问题讨论】:

  • strtok() 是您可以选择的最糟糕的技术之一。
  • 使用std::stringstd::string::find_first_of
  • @PeteBecker - 我使用了endl,因为如果程序因分段错误或其他原因异常结束,则缓冲区可能未被清除。所以为了清除缓冲区并为了安全起见,我使用了 endl
  • @MayankJain - 这就是std::cerr 的用途。

标签: c++


【解决方案1】:
char delims[] = {' ',','};

应该是

char delims[] = " ,";

您传递的是一个字符列表,而不是带有要使用的分隔符列表的 char *,因此出现意外行为,因为 strtok 需要一个以 0 结尾的字符串。在您的情况下,strtok 进入“树林”,并在声明的数组之后使用任何内容进行标记。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多