这是我为回应 C ++ Primer 中的练习而编写的程序。我不知道为什么它会在矢量中打印最后一个数字两次。
vector<int>* create_dyn_vec() {
return new vector<int>();
}
void give_value(vector<int>* ivec_ptr, istream& in) {
int i;
while (in) {
in >> i;
ivec_ptr->push_back(i);
}
}
void print(vector<int>* ivec_ptr) {
for (auto& i : *ivec_ptr)
cout << i << " " << endl;
}
int main() {
auto ivec_dyn_ptr=create_dyn_vec();
give_value(ivec_dyn_ptr, cin);
print(ivec_dyn_ptr);
delete ivec_dyn_ptr;
}
答案 0 :(得分:4)
对于您的重复上一个号码的直接问题,请替换
while (in) {
in >> i;
只是
while( in >> i ) {
在将数字附加到向量之前,原始代码不会检查输入操作是否成功。因此,在文件的末尾,输入操作失败,数字不变,并被附加。
在替换代码中,表达式in >> i
尝试输入操作并生成对流的引用作为其表达式结果。该引用用作while
条件,当用作条件时,它将转换为bool
。该转换由流定义为生成not in.fail()
,其中fail
是成员函数,它告诉您此流上的最后一个i / o操作是否失败或成功。
提示:您可以使用C ++ 引用来代替传递指针。
使用更多惯用的C ++,这段代码就像......
void load_from( istream& in, vector<int>& v )
{
int i;
while( in >> i )
{
v.push_back( i );
}
}
void print( vector<int> const& v )
{
for( auto const& i : v )
{
cout << i << endl;
}
}
int main()
{
vector<int> v;
load_from( cin, v );
print( v );
}
请注意,此处没有new
或delete
个表达式。使用像vector
这样的集合类的重点是它自动化内存管理。在顶部添加手动内存管理而非失败目的。
免责声明:我没有尝试编译代码。
答案 1 :(得分:3)
由于std::istream
上文件条件的结尾在 后设置 ,您尝试从中读取,而不是之前:
while (in) {
in >> i;
ivec_ptr->push_back(i);
}
读完文件中的最后一个值后,再次重新启动while循环:
while (in) {
评估为true
,因为尚未达到文件条件的结尾。
in >> i;
ivec_ptr->push_back(i);
然后尝试读取下一个值。此尝试失败,并在std::istream
上设置文件结束条件。但是你push_back()
仍然是向量的值。这恰好是您在文件中读取的最后一个值,实际上是第二次将其附加到向量中。
在下一次迭代中,文件条件的结束将终止while
循环。