如何在字符串中使用strtok? 编辑:对不起,应该是C++。如何在字符串中使用strtok FQ_ID_line[0]="1,26665;TUK.006.8955.FQ;TUK;400 BB 2 FQ;400 BB 2;899;FQ;Z_SCCFG1;Z_BSCFG1;333"; FQ_ID_line[1]="2,26223;TUK.002.8955.FQ;TUK;400 BB 2 FQ;400 BB 2;;FQ;Z_SCCFG1;Z_BSCFG1;333"; for(int FQ_i=0;FQ_i<FQ_Number;FQ_i++) { printf( "FQ_ID_line[FQ_i]=%u\n", FQ_ID_line[FQ_i] ); char * FQ_array=strdup(FQ_ID_line[FQ_i].c_str()); char *chars_array=strtok(FQ_array,seps); chars_array=strtok(NULL,seps); strcpy(DataLine[FQ_i].analog_comp_id,chars_array); chars_array=strtok(NULL,seps); strcpy(DataLine[FQ_i].RTU_abbr,chars_array); chars_array=strtok(NULL,seps); chars_array=strtok(NULL,seps); chars_array=strtok(NULL,seps); chars_array=strtok(NULL,seps); chars_array=strtok(NULL,seps); strcpy(DataLine[FQ_i].analog_scc_fep_group,chars_array); chars_array=strtok(NULL,seps); strcpy(DataLine[FQ_i].analog_bsc_fep_group,chars_array); chars_array=strtok(NULL,seps); strcpy(DataLine[FQ_i].RTU_number,chars_array); DataLine[FQ_i].float_RTU_number=atof(chars_array); free(FQ_array); } FQ_ID_line[0]=“126665;TUK.006.8955.FQ;TUK;400 BB 2 FQ;400 BB 2;899;FQ;Z_SCCFG1;Z_BSCFG1;333”; FQ_ID_line[1]=“226223;TUK.002.8955.FQ;TUK;400 BB 2 FQ;400 BB 2;;FQ;Z_SCCFG1;Z_BSCF1;333”; 对于(int FQ_i=0;FQ_i

如何在字符串中使用strtok? 编辑:对不起,应该是C++。如何在字符串中使用strtok FQ_ID_line[0]="1,26665;TUK.006.8955.FQ;TUK;400 BB 2 FQ;400 BB 2;899;FQ;Z_SCCFG1;Z_BSCFG1;333"; FQ_ID_line[1]="2,26223;TUK.002.8955.FQ;TUK;400 BB 2 FQ;400 BB 2;;FQ;Z_SCCFG1;Z_BSCFG1;333"; for(int FQ_i=0;FQ_i<FQ_Number;FQ_i++) { printf( "FQ_ID_line[FQ_i]=%u\n", FQ_ID_line[FQ_i] ); char * FQ_array=strdup(FQ_ID_line[FQ_i].c_str()); char *chars_array=strtok(FQ_array,seps); chars_array=strtok(NULL,seps); strcpy(DataLine[FQ_i].analog_comp_id,chars_array); chars_array=strtok(NULL,seps); strcpy(DataLine[FQ_i].RTU_abbr,chars_array); chars_array=strtok(NULL,seps); chars_array=strtok(NULL,seps); chars_array=strtok(NULL,seps); chars_array=strtok(NULL,seps); chars_array=strtok(NULL,seps); strcpy(DataLine[FQ_i].analog_scc_fep_group,chars_array); chars_array=strtok(NULL,seps); strcpy(DataLine[FQ_i].analog_bsc_fep_group,chars_array); chars_array=strtok(NULL,seps); strcpy(DataLine[FQ_i].RTU_number,chars_array); DataLine[FQ_i].float_RTU_number=atof(chars_array); free(FQ_array); } FQ_ID_line[0]=“126665;TUK.006.8955.FQ;TUK;400 BB 2 FQ;400 BB 2;899;FQ;Z_SCCFG1;Z_BSCFG1;333”; FQ_ID_line[1]=“226223;TUK.002.8955.FQ;TUK;400 BB 2 FQ;400 BB 2;;FQ;Z_SCCFG1;Z_BSCF1;333”; 对于(int FQ_i=0;FQ_i,c++,C++,问题的原因: 函数strtok()存在许多问题,因为后续调用依赖于以前的调用,并且此依赖关系是以不安全的方式管理的: < LI>不是线程安全(参见罗伯特评论,C++标准部分21.8 PT 14) 如果您调用的一个函数在您不知道的情况下使用strtok(),那么下一次调用strtok()将返回很多惊喜 现在,您的问题来自输入字符串部分:…400 BB 2;;FQ;…,以及以下定义:在后续调用中,函数(…)将最后一个标记结束后的位置用作扫描的新起始位置。要确定标记的开始和结束,函数首先从起始位置

问题的原因:

函数strtok()存在许多问题,因为后续调用依赖于以前的调用,并且此依赖关系是以不安全的方式管理的:

    < LI>不是线程安全(参见罗伯特评论,C++标准部分21.8 PT 14)
  • 如果您调用的一个函数在您不知道的情况下使用strtok(),那么下一次调用strtok()将返回很多惊喜
现在,您的问题来自输入字符串部分:
…400 BB 2;;FQ;…
,以及以下定义:在后续调用中,函数(…)将最后一个标记结束后的位置用作扫描的新起始位置。要确定标记的开始和结束,函数首先从起始位置扫描分隔符中未包含的第一个字符(即标记的开始)

因此,在返回“400 BB 2”之前,一切都正常工作。根据此算法,下一个“;”将被跳过,您的代码将跳过空字段(;;),就好像它不存在一样。下面的字段并没有任何变化,但您对strtok()的上一次调用甚至可能导致分段错误

解决方案:

<>最好避免Strutok()。如果你喜欢C风格,你可以考虑使用SrpBrk()在代码中进行一些修改。例如:

char* get_field(char*p, char*& next, const char* s) // by ref as it's c++
{
    if ((next = strpbrk(p, s)) != NULL)
        *next++ = '\0';
    return p; 
}
使用以下用法替换strtok():

我的个人建议,用C++,将是<强> >在标准(或升压)中提供的表达式< /强>,这也允许对输入数据进行一致性检查。

完整的代码将如下所示:

regex fmt("([0-9]*,[0-9]*);(.*);(.*);(.*);(.*);(.*);(.*);(.*);(.*);([0-9]*\.*[0-9]*)");

for (int FQ_i = 0; ...)
{
    smatch sm;
    printf("FQ_ID_line[FQ_i]=%u\n", FQ_ID_line[FQ_i]);  // ok, a cout would be better
    if (regex_match(FQ_ID_line[FQ_i], sm, fmt)) {
        DataLine[FQ_i].analog_comp_id = sm[2];
        DataLine[FQ_i].RTU_abbr = sm[3]; 
        DataLine[FQ_i].analog_scc_fep_group = sm[8];
        DataLine[FQ_i].analog_bsc_fep_group = sm[9]; 
        DataLine[FQ_i].RTU_number = sm[10]; 
        DataLine[FQ_i].float_RTU_number = stof(sm[10]); 
    }
    else
        cout << " ** Non matching line ignored !!\n";
}
regexfmt(([0-9]*,[0-9]*);(.*);(.*);(.*);(.*);(.*);(.*);(.*);(.*);([0-9]*\.[0-9]*);
对于(int FQ_i=0;…)
{
smatch sm;
printf(“FQ_ID_行[FQ_i]=%u\n”,FQ_ID_行[FQ_i]);//好的,一个cout会更好
if(正则表达式匹配(FQ_ID_行[FQ_i],sm,fmt)){
数据线[FQ_i]。模拟电路id=sm[2];
数据线[FQ_i].RTU_abbr=sm[3];
数据线[FQ_i]。模拟scc_fep_组=sm[8];
数据线[FQ_i]。模拟_bsc_fep_组=sm[9];
数据线[FQ_i].RTU_编号=sm[10];
数据线[FQ_i]。浮点数=stof(sm[10]);
}
其他的

代码看起来主要像C,但是你把问题标记为C++——是什么?你想要一个C解决方案(C库函数如<代码> Sttokk < /C> >,代码> StrucP< /Cube >等)还是一个适当的C++解决方案?是C++…有一个“CUT”像通常一样,有人进入C++中,因为它的一个最有用的特性而不是所有的强大的特性。它可能是C++,因为它是c++,但是在它的精神中,它看起来像C,具有所有的StrucYe()、Strutok()、For()、Primff()等等。这两个相邻的分号被一个代码“Stotok(null,SEPS)吞没)。
。最好使用
string
的函数来解析输入。
regex fmt("([0-9]*,[0-9]*);(.*);(.*);(.*);(.*);(.*);(.*);(.*);(.*);([0-9]*\.*[0-9]*)");

for (int FQ_i = 0; ...)
{
    smatch sm;
    printf("FQ_ID_line[FQ_i]=%u\n", FQ_ID_line[FQ_i]);  // ok, a cout would be better
    if (regex_match(FQ_ID_line[FQ_i], sm, fmt)) {
        DataLine[FQ_i].analog_comp_id = sm[2];
        DataLine[FQ_i].RTU_abbr = sm[3]; 
        DataLine[FQ_i].analog_scc_fep_group = sm[8];
        DataLine[FQ_i].analog_bsc_fep_group = sm[9]; 
        DataLine[FQ_i].RTU_number = sm[10]; 
        DataLine[FQ_i].float_RTU_number = stof(sm[10]); 
    }
    else
        cout << " ** Non matching line ignored !!\n";
}