简体   繁体   English

如何将矢量转换为字符串并转换回矢量

[英]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个程序,第一个程序执行以下任务:

  1. Has a vector of integers 有一个整数向量
  2. convert it into array of string 将其转换为字符串数组
  3. write it in a file 把它写在一个文件中

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 : 第二个程序将执行以下任务:

  1. read the file 读取文件
  2. convert the array of string back into original vector 将字符串数组转换回原始向量

----------------- 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. 发布时, 请发布一个完整的最小工作示例 ,必须添加#includemain和时间更好地花时间帮助。 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(','));
    }
}
  1. istringstream (stringword) >> value interprets the data up to the comma as an integer, the first value, which is then stored. istringstream (stringword) >> value将数据解释为逗号作为整数,第一个值然后存储。

  2. 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

  3. 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。

  4. 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,

  • The loop executes normally three times 循环正常执行三次
  • The fourth time, stringword is 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM