将字符串添加到vector <const char =“”* =“”>使用strtok()</const>给出了奇怪的行为

时间:2013-09-30 02:16:38

标签: c++ file-io vector strtok

我正在尝试将从strtok返回的字符串添加到向量中,但由于某种原因,它只添加文件中的最后一个字符串...

代码:

// read the remaining lines
// put address and ports into ipaddr and ports, respectively
for (unsigned i = 0; i < numStones; ++i) {
    const char * item;
    fgets(buffer, 255, fp);
    //printf("%s", buffer);
    item = strtok(buffer, " ");
    printf("%s\n", item);
    ipaddr.push_back(item);
    item = strtok(NULL, "\n"); 
    printf("%s\n", item);
    ports.push_back(item);
}
#ifdef _DEBUG
for (unsigned i = 0; i < numStones; i++) {
    printf("IP Address %d: %s\n", i, ipaddr.at(i));
    printf("Port %d: %s\n", i, ports.at(i));
}
#endif

输出:

129.82.47.21
3360
129.82.47.22
5540
129.82.47.23
7732
129.82.47.24
8896
IP Address 0: 129.82.47.24
Port 0: 8896
IP Address 1: 129.82.47.24
Port 1: 8896
IP Address 2: 129.82.47.24
Port 2: 8896
IP Address 3: 129.82.47.24
Port 3: 8896

如您所见,代码从tokenizer获取正确的字符串,但没有将正确的字符串推送到向量。这让我疯了,帮帮忙,谢谢你!

3 个答案:

答案 0 :(得分:3)

因为你在不分配新内存的情况下推送指针。你总是提供指向缓冲区中某个位置的指针。

在C语言中,您可以使用strdup复制字符串。

在C ++中,您通常会构建一个std::string并将其存储在向量中而不是char *中。但是,您可能拥有自己的内存管理方案,并在某处存储字符串缓冲区。或者,如果需要,可以使用strdup

我普遍同意乔纳森波特对另一个答案的评论:

  

不鼓励在向量中存储指针

如果您不熟悉编程,则应该100%接受该建议。当你更高级时,有时候将指针放在向量中是完全合法的。


[edit] 澄清。

快速解决方法是这样的(是的,我们通常应该检查strdup没有返回NULL):

ports.push_back(strdup(item));

但这会产生一个清理工作,因为当你完成向量时,你需要释放所有这些指针:

for( int i = 0; i < ports.size(); i++ ) free(ports[i]);

更好的解决方法是使用std::vector<std::string>作为您的数据类型,它将为您处理内存。

答案 1 :(得分:0)

你推入向量的是指针。在for之后,向量存储相同的内存位置numStones次。如果要保存真实信息,new a用于保存的内存块,然后将其推送到矢量中。

答案 2 :(得分:0)

这也发生在我身上。主要是这些评论对我有帮助。您必须创建一个char*辅助变量,并在每次读取新字符串时将其设置为新,以便每次都将使用新的地址。之后你只需push_back。 像

char* aux = new char[100]; strcpy(aux, your_str); vector.push_back(aux);