在其多个'\ 0'字符处拆分char *

时间:2011-06-13 01:40:41

标签: c++ winapi cstring

以下是C ++。 我有一个字符串,其中包含我需要在每个变量的声明中拆分它的环境变量。将其存储在一个字符串中:

char* envVars = "=::=::\0system=blah\0othervar=blah\0"

所以我使用cstring函数在空终结符char'\ 0'出现时拆分字符串,但它只是进入无限循环。为什么呢?

找到解决方案:查看代码注释:

vector <string> GetEvironmentVariables()
{
   vector <string> envVariables;
   char* environVar = GetEnvironmentStrings();
   char* pos        = strchr( environVar, '\0' );

   // As far as I know environVar =::=::\0environVar1=...\0environVar2=...\0" 
   // so the string has many NULL terminators  

   while ( pos != NULL )
   {
       char* buffer;
       strncpy( buffer, environVar, strlen(pos) );   // on the 1st iteration: buffer SHOULD = "=::=::\0", 2nd buffer SHOULD = "environVar=...\0"
       envVariables.push_back( string(buffer) );
       environVar = pos;                            // SOLUTUION: I need to move over the '\0' pos points to so: environVar = ++pos;
       pos        = strchr( environVar, '\0' );

       printf("Var: %s \n", envVariables.back().c_str() ); 
       printf("env: %s \n", environVar);
       system("PAUSE");
       // prints out this:
       // Var: cRek (same junk each iteration)
       // env: 
       // Press any key to continue....
   }

   FreeEnvironmentStrings( environVar ); 
   return envVariables;       
}

4 个答案:

答案 0 :(得分:8)

您可以更简单地执行此操作,而无需依赖C标准库函数:

#include <string>
#include <vector>

int main()
{
    const char* environment = "x=x\0y=y\0z=z\0";

    std::vector<std::string> environment_strings;
    const char* current_string = environment;

    while (*current_string)
    {
        environment_strings.push_back(current_string);
        current_string += environment_strings.back().length() + 1;
    }
}

此处使用的std::string构造函数从指向数组中获取字符,直到达到\0。然后我们移动到下一个字符串,该字符串从前一个字符串结尾开始一个字符。当它到达&#34;空&#34;它停止string(结束序列的double null终止符)。

答案 1 :(得分:2)

我原本预计会立即退出,但实际上该手册页说:

  

终止空字符被认为是字符串的一部分;因此,如果c'\0',则函数会找到终止'\0'

当然,pos = strchr(environVar, '\0');的结果是*pos == '\0'strlen(pos) == 0。所以你总是复制零个字符。没用。

您还可以设置environVar = pos;,而不会跳过NUL字符。因此,对strchr的下一次调用将返回environVar,并且不再有任何进展。


你也忘了初始化buffer,你传递了一个指向strncpy的狂野指针,它会破坏内存的随机部分。这个bug可能会后面一旦你确定了长度参数总是为零的事实,它的丑陋头脑。

答案 2 :(得分:0)

#include <cstring>
#include <string>
#include <vector>

using namespace std;

int main ()
{
    vector<string> res;

    const char *s = "=::=::\0system=blah\0othervar=blah\0";
    const char *p = s;

    while (*s != '\0')
    {
        p = strchr (p, '\0');
        res.push_back (s);
        s = ++p;
    }
}

答案 3 :(得分:0)

这条线错了。

strncpy( buffer, environVar, strlen(pos) );

pos位于第一个null,长度为零。你可能想要strlen(environVar)。

这一行可能导致无限循环:

environVar = pos;

由于pos位于\ 0,它将返回相同的指针。试试pos + 1.