1

我对使用strtok()函数没有什么问题。我正在解析两个文件。首先我将文件 1 加载到buffer. 该文件包含我需要加载的第二个文件的名称。这两个文件都是逐行读取的。我的代码如下所示:

char second_file_name[128] = { "" };
char * line = strtok( buffer, "\n" );
while( line != NULL )
{
  if ( line[0] = 'f' )
  {
    sscanf( line, "%*s %s", &second_file_name );
    LoadSecondFile( second_file_name );
  }
  // processing other lines, not relevant for question
  line = strtok( NULL, "\n" );
}

虽然该LoadSecondFile(...)功能以几乎相同的方式工作,因此:

char * line = strtok( buffer, "\n" );
while( line != NULL )
{
  // process file data
  line = strtok( NULL, "\n" );
}

我的问题是,在调用LoadSecondFile(...)函数后,strtok()用于解析第一个文件的指针“搞砸了”。它没有给我第二个文件名称之后的行,而是什么都没有给我 - 理解为“完全胡说八道”。我是否正确地认为这是由strtok()程序中共享的指针引起的,而不仅仅是在函数中?如果是这样,在使用它解析第二个文件之前,如何“备份”strtok()用于解析第一个文件的指针?

感谢您的任何建议。干杯。

4

3 回答 3

7

strtok是一个维护全局状态的邪恶小函数,因此(如您所见)您不能同时标记两个字符串。strtok_r在某些平台上,名称为or的邪恶变体较少strtok_s;但是既然你写的是 C++ 而不是 C,为什么不使用 C++ 库呢?

ifstream first_file(first_file_name);      // no need to read into a buffer
string line;
while (getline(first_file, line)) {
    if (!line.empty() && line[0] == 'f') { // NOT =
        istringstream line_stream(line);
        string second_file_name;
        line_stream.ignore(' ');           // skip first word ("%*s")
        line_stream >> second_file_name;   // read second word ("%s")
        LoadSecondFile(second_file_name);
    }
}
于 2013-08-22T11:49:29.493 回答
3

您可以使用strtok_rwhich 允许您拥有不同的状态指针。

于 2013-08-22T11:39:28.793 回答
3

这就是为什么不断建议不要使用strtok (更不用说线程问题)的原因。有许多更好的解决方案,使用 C++ 标准库中的函数。没有一个修改他们正在处理的文本,也没有一个使用隐藏的静态状态。

于 2013-08-22T11:41:50.540 回答