【问题标题】:Why is my string parsed differently via strtok on Windows and Linux?为什么我的字符串在 Windows 和 Linux 上通过 strtok 解析不同?
【发布时间】:2011-04-17 12:40:30
【问题描述】:

在我的程序中,我正在使用 strtok 切割我的 char*。当我在 Windows 上检查时,它就像我想要的那样被削减,但是当我在 Linux 上做同样的事情时,它做错了。

示例:

窗口:

  • 我的 char*(行)是:“1,21-344-32,blabla”
  • 在我第一次执行 strtok 时,我得到“1”
  • 第二次得到“21-344-32”

Linux:

  • 我的 char*(行)是:“1,21-344-32,blabla”
  • 在我第一次执行 strtok 时,我得到“1”
  • 第二次得到“2”

代码

Result FileReader::InitRead (Manager* mngr, char* pfileName, ofstream &ResultFile)//add /*Manager* mng,*/ + use for: vehicle init
{
     FILE *pfile;
     char fileName[50],line[2000], *word= NULL,*str1=NULL,*str2=NULL,*str3=NULL, *str4=NULL, *str5=NULL, *str6=NULL;
     int wcount=0,lcount=0;
     Vehicle::Vehicle_Type vecEnm = Vehicle::InvalidCarEm;
     bool stop = false;
     string check;

     strcpy(fileName,pfileName);

     if((pfile = fopen(fileName, "r")) == NULL) 
     {
         ResultFile<<"Error Opening vehicles init file, May not exist.\n";
         return Fail;
     }
     else
     { 
      while( fgets(line, sizeof(line), pfile) != NULL ) 
      {
       lcount++;
       wcount=0;
       check.assign(line);
       if(check.size()!=0){
       word = strtok (line,",");
       if ((word[0] != '#') &&  (word[0] != '\r') && (strcmp(line,"\n") != 0))
       {
           wcount++;
           str1 = word;
           vecEnm = (Vehicle::Vehicle_Type)(atoi(str1));
           while ((word != NULL) &&  (wcount < 7) && (!stop))
           {
                 wcount ++;
                 word = strtok (NULL, ",");

                 switch (wcount)
                 {
                        case 2: str2 = word;
                              break;
                        case 3: str3 = word;
                              break;
                        case 4: str4 = word;
                              break;
                        case 5: str5 = word;
                              if ((vecEnm < Vehicle::PlaneEm) || (vecEnm == Vehicle::InvalidCarEm))
                                    stop=true;
                              break;
                        case 6: str6 = word;
                              break;
                        default:break;
                 }
            }

            mngr->TranslateVecInit(vecEnm,str2,str3,str4,str5,str6,ResultFile);

           }//while - line not finished
       }
       str1=str2=str3=str4=str5=str6=NULL;
       stop=false;

       }//reads next line
       fclose(pfile); 
       }
 return Success;
}

【问题讨论】:

  • 你如何观察到你得到“2”?我建议将 strtok 的结果记录到控制台/文件以避免任何疑问。
  • 它适用于我(gcc 4.3.4)。你能用 main() 发布一个完整的工作示例吗?
  • 您是否有机会使用多个线程? strtok 不是线程安全的。
  • 不确定这与您的问题有关,但请记住 strtok 修改原始字符串。它不会复制它。这似乎让很多刚开始使用 C/C++ 的人感到困惑。
  • re:通过调试器观察——你确定你的调试器将你的 char* 解释为一个指向字符串的指针,而不仅仅是一个字符?这就是我建议记录的原因,以消除调试器的特殊性。

标签: c++ linux cross-platform token tokenize


【解决方案1】:

我在 C 语言中遇到了同样的问题。我的代码在 Windows 上运行良好,但在 Linux 中使用 strtok() 时一直出错。我只是忘记包含string.h

#include <string.h>

【讨论】:

    【解决方案2】:

    我在您的代码中没有发现任何错误,但我强烈建议使用 strtok_r() 而不是 strtok()。我觉得 strtok 应该被淘汰,它在 MT 环境中不安全。 另外我认为 strtok_r 将帮助您轻松找到错误,因为它有另一个参数来跟踪解析进度,因此很容易找到错误: http://www.mkssoftware.com/docs/man3/strtok_r.3.asp

    【讨论】:

      猜你喜欢
      • 2012-03-29
      • 1970-01-01
      • 2011-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-11
      相关资源
      最近更新 更多