[英]How to convert vector to string and convert back to vector
----------------- EDIT ----------------------- -----------------编辑-----------------------
Based on juanchopanza's comment : I edit the title 根据juanchopanza的评论:我编辑标题
Based on jrok's comment : I'm using ofstream to write, and ifstream to read. 基于jrok的评论:我正在使用ofstream来编写,而ifstream则用于阅读。
I'm writing 2 programs, first program do the following tasks : 我正在编写2个程序,第一个程序执行以下任务:
The code of the first program : 第一个程序的代码:
vector<int> v = {10, 200, 3000, 40000};
int i;
stringstream sw;
string stringword;
cout << "Original vector = ";
for (i=0;i<v.size();i++)
{
cout << v.at(i) << " " ;
}
cout << endl;
for (i=0;i<v.size();i++)
{
sw << v[i];
}
stringword = sw.str();
cout << "Vector in array of string : "<< stringword << endl;
ofstream myfile;
myfile.open ("writtentext");
myfile << stringword;
myfile.close();
The output of the first program : 第一个程序的输出:
Original vector : 10 200 3000 40000
Vector in string : 10200300040000
Writing to File .....
second program will do the following tasks : 第二个程序将执行以下任务:
----------------- EDIT ----------------------- -----------------编辑-----------------------
Now the writing and reading is fine, thanks to Shark and Jrok,I am using a comma as a separator. 现在写作和阅读都很好,感谢Shark和Jrok,我使用逗号作为分隔符。 The output of first program : 第一个程序的输出:
Vector in string : 10,200,3000,40000,
Then I wrote the rest of 2nd program : 然后我写了第二个程序的其余部分:
string stringword;
ifstream myfile;
myfile.open ("writtentext");
getline (myfile,stringword);
cout << "Read From File = " << stringword << endl;
cout << "Convert back to vector = " ;
for (int i=0;i<stringword.length();i++)
{
if (stringword.find(','))
{
int value;
istringstream (stringword) >> value;
v.push_back(value);
stringword.erase(0, stringword.find(','));
}
}
for (int j=0;j<v.size();i++)
{
cout << v.at(i) << " " ;
}
But it can only convert and push back the first element, the rest is erased. 但它只能转换并推回第一个元素,其余元素将被删除。 Here is the output : 这是输出:
Read From File = 10,200,3000,40000,
Convert back to vector = 10
What did I do wrong? 我做错了什么? Thanks 谢谢
The easiest thing would be to insert a space character as a separator when you're writing, as that's the default separator for operator>>
最简单的方法是在写入时插入空格字符作为分隔符,因为这是operator>>
的默认分隔operator>>
sw << v[i] << ' ';
Now you can read back into an int
variable directly, formatted stream input will do the conversion for you automatically. 现在你可以直接读回一个int
变量,格式化的流输入会自动为你做转换。 Use vector's push_back
method to add values to it as you go. 使用vector的push_back
方法可以随时添加值。
Yes, this question is over a year old, and probably completely irrelevant to the original asker, but Google led me here so it might lead others here too. 是的,这个问题已经超过一年了,可能与原始提问者完全无关,但谷歌带领我到这里,所以它也可能引领其他人。
When posting, please post a complete minimal working example , having to add #include
and main
and stuff is time better spent helping. 发布时, 请发布一个完整的最小工作示例 ,必须添加#include
和main
和时间更好地花时间帮助。 It's also important because of your very problem. 由于你的问题,它也很重要。
Why your second code isn't working is all in this block 为什么你的第二个代码不能正常运行
for (int i=0;i<stringword.length();i++)
{
if (stringword.find(','))
{
int value;
istringstream (stringword) >> value;
v.push_back(value);
stringword.erase(0, stringword.find(','));
}
}
istringstream (stringword) >> value
interprets the data up to the comma as an integer, the first value, which is then stored. istringstream (stringword) >> value
将数据解释为逗号作为整数,第一个值然后存储。
stringword.find(',')
gets you the 0-indexed position of the comma. stringword.find(',')
获取逗号的0索引位置。 A return value of 0 means that the character is the first character in the string, it does not tell you whether there is a comma in the string. 返回值为0表示该字符是字符串中的第一个字符,它不会告诉您字符串中是否有逗号。 In that case, the return value would be string::npos
. 在这种情况下,返回值将是string::npos
。
stringword.erase
deletes that many characters from the start of the string. stringword.erase
从字符串的开头删除那么多字符。 In this case, it deletes 10
, making stringword ,200,3000,40000
. 在这种情况下,它删除10
,使stringword ,200,3000,40000
。 This means that in the next iteration stringword.find(',')
returns 0. 这意味着在下一次迭代中, stringword.find(',')
返回0。
if (stringword.find(','))
does not behave as wished. if (stringword.find(','))
表现不如希望的那样。 if(0)
casts the integer to a bool
, where 0 is false
and everything else is true
. if(0)
将整数强制转换为bool
,其中0为false
,其他一切都为true
。 Therefore, it never enters the if-block again, as the next iterations will keep checking against this unchanged string. 因此,它永远不会再次进入if块,因为下一次迭代将继续检查这个未更改的字符串。
And besides all that there's this: 除此之外还有这个:
for (int j=0;j<v.size();i++)
{
cout << v.at(i) << " " ;
}
it uses i
. 它使用i
。 That was declared in a for loop, in a different scope. 这是在for循环中声明的,在不同的范围内。
The code you gave simply doesn't compile, even with the added main and includes. 您提供的代码根本无法编译,即使添加了main和includes。 Heck, v
isn't even defined in the second program. 哎呀, v
甚至没有在第二个程序中定义。
It is however not enough, as the for condition stringword.length()
is recalculated every loop. 然而,这是不够的,因为每个循环都会重新计算条件stringword.length()
。 In this specific instance it works, because your integers get an extra digit each time, but let's say your input file is 1,2,3,4,
: 在这个特定的例子中它可以工作,因为你的整数每次都得到一个额外的数字,但是假设你的输入文件是1,2,3,4,
4,
stringword.length()
returns 2, but i
is already valued 3, so i<stringword.length()
is invalid, and the loop exits. 第四次,stringword为4,
stringword.length()
返回2,但i
值已经为3,所以i<stringword.length()
无效,循环退出。 If you want to use the string's length as a condition, but edit the string during processing, store the value before editing. 如果要将字符串的长度用作条件,但在处理期间编辑字符串,请在编辑之前存储该值。 Even if you don't edit the string, this means less calls to length()
. 即使您不编辑字符串,这意味着对length()
调用也会减少。
If you save length beforehand, in this new scenario that would be 8. However, after 4 loops string is already empty, and it executes the for loop some more times with no effect. 如果你预先保存长度,在这个新的场景中将是8.但是,在4个循环后,字符串已经为空,并且它执行for循环多次而没有效果。
Instead, as we are editing the string to become empty, check for that. 相反,当我们将字符串编辑为空时,检查它。
All this together makes for radically different code altogether to make this work: 所有这些共同构成完全不同的代码使这项工作:
while (!stringword.empty())
{
int value;
istringstream (stringword) >> value;
v.push_back(value);
stringword.erase(0, stringword.find(',')+1);
}
for (int i = 0; i < v.size(); i++)
{
cout << v.at(i) << " " ;
}
A different way to solve this would have been to not try to find from the start, but from index i onwards, leaving a string of commas. 解决这个问题的另一种方法是不要试图从一开始就找到,而是从索引i开始,留下一串逗号。 But why stick to messy stuff if you can just do this. 但是,如果你能做到这一点,为什么要坚持使用凌乱的东西。
And that's about it. 这就是它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.