我正在尝试将从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获取正确的字符串,但没有将正确的字符串推送到向量。这让我疯了,帮帮忙,谢谢你!
答案 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);