C++primer 关于sstream的一道题目

skyhigh1987 2009-02-20 12:22:54
题目:编写程序将文件中的每一行存储在 vector<string> 容器对象中,然后使用 istringstream 从 vector 里以每次读一个单词的形式读取存储的行。
我的代码:

#include <sstream>
#include <vector>
#include <fstream>
#include <string>
#include "8.13.h"
#include <iostream>

using namespace std;

int fileToVector(string fileName, vector<string>& vec)
{
ifstream fin;
string line;
vector<string>::iterator it=vec.begin();

open_file(fin, fileName);// 打开文件

if(!fin)// 若打开文件失败
{
return 1;
}

while(getline(fin,line))// 读文件直到文件结束符
{
vec.push_back(line);// 将文件流存入向量
}

fin.close();// 关闭文件

if(fin.eof())// 文件结束符
{
return 4;
}
if(fin.fail())// 发生系统故障
{
return 2;
}
if(fin.bad())// 读入数据失败
{
return 3;
}

}

int main()
{
string fileName;
vector<string> vec;
string word;
istringstream instr;

cout << "enter filename: ";// 提示输入待打开的文件名
cin >> fileName;// 输入待打开的文件

switch(fileToVector(fileName, vec))
{
case 1:
cout << "can't open file: " << fileName << endl;
return -1;
break;
case 2:
cout << "systerm fails" << endl;
return -1;
break;
case 3:
cout << "bad data" << endl;
return -1;
break;
}

//若成功打开文件且实现了文件流到向量的存储

for(vector<string>::iterator it=vec.begin(); it!=vec.end(); ++it)
{
instr.str(*it);
while(instr >> word)
{
cout << word << endl;
}
}

return 0;
}

问题是:当我把main函数中访问vector的迭代器的定义和初始化放到main的开头,即
int main()
{
...
vector<string>::iterator it=vec.begin();
...
...
...
...
...
for(; it!=vec.end(); ++it)
{
instr.str(*it);
while(instr >> word)
{
cout << word << endl;
}
}

return 0;
}
在VC6.0下运行,会弹出一个“应用程序错误”的对话框。这是怎么回事呢?
...全文
148 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
Dinelgua 2009-02-20
  • 打赏
  • 举报
回复
因为vec 在你初始化interator后 发生了变化

此句导致 vec变化 switch(fileToVector(fileName, vec))
vec 原有内存不够存储新内容时 STL会心分配一个两倍于原有内存或更大的内存
然后将原来内存中内容 拷贝到新内存中

这是 it 指向的还是老内存的begin位置
而实际上 vec 已经在新的内存位置上了

这时使用it来访问已经不属于vec的内存当然非法 导致程序崩溃
skyhigh1987 2009-02-20
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 fhtingtian 的回复:]
vc6还是不要用了
[/Quote]
why not?
skyhigh1987 2009-02-20
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 chin_chen 的回复:]
引用楼主 skyhigh1987 的帖子:
题是:当我把main函数中访问vector的迭代器的定义和初始化放到main的开头,即
int main()
{
...
vector <string>::iterator it=vec.begin();
...
...
...
...
...
for(; it!=vec.end(); ++it)
{
instr.str(*it);
while(instr >> word)
{
cout < < word < < endl;
}
}

return 0;
}
在VC6.0下运行,会弹出一个“应用程序错误”的对话框。…
[/Quote]
不可以放开头吗?
bfhtian 2009-02-20
  • 打赏
  • 举报
回复
vc6还是不要用了
chin_chen 2009-02-20
  • 打赏
  • 举报
回复
[Quote=引用楼主 skyhigh1987 的帖子:]
题是:当我把main函数中访问vector的迭代器的定义和初始化放到main的开头,即
int main()
{
...
vector <string>::iterator it=vec.begin();
...
...
...
...
...
for(; it!=vec.end(); ++it)
{
instr.str(*it);
while(instr >> word)
{
cout < < word < < endl;
}
}

return 0;
}
在VC6.0下运行,会弹出一个“应用程序错误”的对话框。这是怎么回事呢?
[/Quote]
可以放着,为啥要放开头
jakqigle 2009-02-20
  • 打赏
  • 举报
回复

#include <sstream>
#include <vector>
#include <fstream>
#include <string>
#include <iostream>

using namespace std;

int fileToVector(string fileName, vector<string>& vec)
{
string line,filename("tt.txt");
vector<string>::iterator it=vec.begin();

ifstream fin(filename.c_str());// 打开文件

if(!fin)// 若打开文件失败
{
return 1;
}

while(getline(fin,line))// 读文件直到文件结束符
{
vec.push_back(line);// 将文件流存入向量
}

fin.close();// 关闭文件

if(fin.eof())// 文件结束符
{
return 4;
}
if(fin.fail())// 发生系统故障
{
return 2;
}
if(fin.bad())// 读入数据失败
{
return 3;
}

}

int main()
{
string fileName;
vector<string> vec;
string word;
istringstream instr;

cout << "enter filename: ";// 提示输入待打开的文件名
cin >> fileName;// 输入待打开的文件

switch(fileToVector(fileName, vec))
{
case 1:
cout << "can't open file: " << fileName << endl;
return -1;
break;
case 2:
cout << "systerm fails" << endl;
return -1;
break;
case 3:
cout << "bad data" << endl;
return -1;
break;
}

//若成功打开文件且实现了文件流到向量的存储

for(vector<string>::iterator it=vec.begin(); it!=vec.end(); ++it)
{
instr.str(*it);
while(instr >> word)
{
cout << word << endl;
}
}

return 0;
}

用vs编译运行正常。
skyhigh1987 2009-02-20
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 waizqfor 的回复:]
引用 3 楼 skyhigh1987 的回复:
引用 1 楼 chin_chen 的回复:
引用楼主 skyhigh1987 的帖子:
题是:当我把main函数中访问vector的迭代器的定义和初始化放到main的开头,即
int main()
{
...
vector <string>::iterator it=vec.begin();
...
...
...
...
...
for(; it!=vec.end(); ++it)
{
instr.str(*it);
while(instr >> word)
{
cout < < word < < endl;
}
}

retur…
[/Quote]
可能不是VC6的问题吧?好像是vector在内存中的机制我没搞懂.请问能不能再详细点
skyhigh1987 2009-02-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 Dinelgua 的回复:]
因为vec 在你初始化interator后 发生了变化

此句导致 vec变化 switch(fileToVector(fileName, vec))
vec 原有内存不够存储新内容时 STL会心分配一个两倍于原有内存或更大的内存
然后将原来内存中内容 拷贝到新内存中

这是 it 指向的还是老内存的begin位置
而实际上 vec 已经在新的内存位置上了

这时使用it来访问已经不属于vec的内存当然非法 导致程序崩溃
[/Quote]
really?
vec中本来没有元素,我在fileToVector(fileName, vec)中用push_back函数添加元素,难道每添加一个元素STL就会分配一个新内存?
定义vec时分配了内存空间吗?如果分配了,为什么push_back新元素之后,vec的内存位置就变了,push_back函数实现的不是在vector“尾部”添加元素吗?
wy2001wy 2009-02-20
  • 打赏
  • 举报
回复
肯定不能放在开头啊,fileToVector函数里面改了vec里的内容,begin和end都不对了,肯定会出错嘛.
waizqfor 2009-02-20
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 skyhigh1987 的回复:]
引用 1 楼 chin_chen 的回复:
引用楼主 skyhigh1987 的帖子:
题是:当我把main函数中访问vector的迭代器的定义和初始化放到main的开头,即
int main()
{
...
vector <string>::iterator it=vec.begin();
...
...
...
...
...
for(; it!=vec.end(); ++it)
{
instr.str(*it);
while(instr >> word)
{
cout < < word < < endl;
}
}

return 0;
}
在VC6.0下运行,会弹出…
[/Quote]
建议LZ换编译器吧 别用VC6了 你访问提前就会造成程序崩溃
这时的内存的存储结构发生变化
pengzhixi 2009-02-20
  • 打赏
  • 举报
回复
听说VC6.0有些东西不支持吧
chenyingshu 2009-02-20
  • 打赏
  • 举报
回复
vs好,用这个吧

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧