0

- - - - - - - - - 编辑 - - - - - - - - - - - -

基于 juanchopanza 的评论:我编辑标题

基于 jrok 的评论:我使用 ofstream 来编写,使用 ifstream 来读取。

我正在编写 2 个程序,第一个程序执行以下任务:

  1. 有一个整数向量
  2. 将其转换为字符串数组
  3. 把它写在一个文件中

第一个程序的代码:

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();

第一个程序的输出:

Original vector : 10 200 3000 40000
Vector in string : 10200300040000
Writing to File ..... 

第二个程序将执行以下任务:

  1. 读取文件
  2. 将字符串数组转换回原始向量

- - - - - - - - - 编辑 - - - - - - - - - - - -

现在写作和阅读都很好,感谢 Shark 和 Jrok,我使用逗号作为分隔符。第一个程序的输出:

Vector in string : 10,200,3000,40000,

然后我写了第二个程序的其余部分:

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) << " " ;
}

但它只能转换和推回第一个元素,其余的被擦除。这是输出:

Read From File = 10,200,3000,40000,
Convert back to vector = 10

我做错了什么?谢谢

4

2 回答 2

1

最简单的方法是在编写时插入一个空格字符作为分隔符,因为这是默认的分隔符operator>>

sw << v[i] << ' ';

现在您可以直接读回int变量,格式化的流输入将自动为您进行转换。使用vector的push_back方法在你去的时候为其添加值。

于 2013-08-19T16:58:15.467 回答
1

是的,这个问题已经有一年多了,可能与最初的提问者完全无关,但是谷歌把我带到了这里,所以它也可能把其他人也带到了这里。

发布时,请发布一个完整的最小工作示例,必须添加#include和其他main内容最好花时间提供帮助。由于您的问题,这也很重要。

为什么您的第二个代码不起作用都在这个块中

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将直到逗号的数据解释为整数,即第一个值,然后将其存储。

  2. stringword.find(',')获取逗号的 0 索引位置。返回值 0 表示该字符是字符串中的第一个字符,它不会告诉您字符串中是否有逗号。在这种情况下,返回值将是string::npos.

  3. stringword.erase从字符串的开头删除那么多字符。在这种情况下,它会删除10,生成 stringword ,200,3000,40000。这意味着在下一次迭代中stringword.find(',')返回 0。

  4. if (stringword.find(','))不按预期行事。if(0)将整数转换为 a bool,其中 0 是false,其他都是true。因此,它永远不会再次进入 if 块,因为下一次迭代将继续检查这个未更改的字符串。

除此之外,还有:

for (int j=0;j<v.size();i++) 
{
    cout << v.at(i) << " " ;
}

它使用i. 这是在 for 循环中声明的,在不同的范围内。
您提供的代码根本无法编译,即使添加了 main 和包含。哎呀,v甚至没有在第二个程序中定义。

然而,这还不够,因为stringword.length()每个循环都会重新计算 for 条件。在这个特定的例子中它可以工作,因为你的整数每次都会得到一个额外的数字,但是假设你的输入文件是1,2,3,4,

  • 循环正常执行3次
  • 第四次,stringword4, stringword.length()返回 2,但i已经是 3,所以i<stringword.length()无效,循环退出。

如果您想使用字符串的长度作为条件,但在处理过程中编辑字符串,请在编辑之前存储该值。即使您不编辑字符串,这也意味着对length().

如果您预先保存长度,在这个新场景中将是 8。但是,在 4 次循环之后,字符串已经为空,并且它执行 for 循环更多次而没有效果。

相反,当我们将字符串编辑为空时,请检查它。

所有这些共同构成了完全不同的代码来完成这项工作:

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) << " " ;
}

解决此问题的另一种方法是不要尝试从头开始查找,而是从索引 i 开始查找,留下一串逗号。但是,如果你能做到这一点,为什么还要坚持凌乱的东西。

就是这样。

于 2014-11-27T14:56:37.770 回答