C++ 从文件导入数据时遇到问题。我有一个无休止的循环
我可以让我的文件加载1个完整结构。但是当我尝试遍历文件时,我有一个无休止的循环,没有加载任何数据。我已附上我的代码和平面文件C++ 从文件导入数据时遇到问题。我有一个无休止的循环,c++,codeblocks,ifstream,C++,Codeblocks,Ifstream,我可以让我的文件加载1个完整结构。但是当我尝试遍历文件时,我有一个无休止的循环,没有加载任何数据。我已附上我的代码和平面文件 #include <iostream> #include <string.h> #include <vector> #include <fstream> using namespace std; typedef struct video_items{ string Title; int YOP;
#include <iostream>
#include <string.h>
#include <vector>
#include <fstream>
using namespace std;
typedef struct video_items{
string Title;
int YOP;
string Category;
float Gross;
}video;
void LoadMovies (vector<video> &v);
void SearchMovies (vector <video> &v, string s);
int main()
{
vector <video> v;
LoadMovies(v);
cout<<"Total number of movies: "<<v.size()<<endl;
for (unsigned int i=0; i<v.size(); ++i) {
cout<<"----------------------------------------------------"<<endl;
cout<<v[i].Title<<endl;
cout<<"Category: "<<v[i].Category<<endl;
cout<<"Year of Publication: "<<v[i].YOP<<endl;
cout<<"Gross: "<<v[i].Gross<<endl;
cout<<"----------------------------------------------------"<<endl<<endl;
}
string WantMovie;
cout<<"Please type in what movie you want."<<endl;
cin>>WantMovie;
SearchMovies(v,WantMovie);
return 0;
}
void LoadMovies (vector<video> &v)
{
video L;
ifstream myfile;
myfile.open ("Movies.txt");
if (myfile.is_open())
{
cout <<"Loading Movie Catalog..."<<endl<<endl;
int i=0;
while (!myfile.eof())
{
myfile.ignore();
//cout<<i<<endl<<endl;
v.push_back(L);
getline(myfile,v[i].Title);
getline(myfile,v[i].Category);
myfile>>v[i].YOP;
myfile>>v[i].Gross;
i++;
}
myfile.close();
}
else cout<<"Unable to open file."<<endl;
}
void SearchMovies (vector <video> &v, string s)
{
s[0] = toupper(s[0]);
unsigned int i;
for (i=0; i<v.size(); i++)
{
if (v[i].Title.compare(0,s.size(),s)==0)
{
break;
}
}
if (i >=v.size()){
i =0;
}
switch(i)
{
case 1:cout<<"You have chosen "<<s<<endl;
break;
default:
cout<<"That movie is not currently in the library, please choose a different one."<<endl;
break;
}
}
如果您仍然陷于困境,那么考虑一下从数据文件中读取每个结构需要完成哪些工作。您需要读取4条信息,2字符串,1整型,1浮点型。您认为读入临时结构
L
是正确的,但您要做的是在将L
添加到向量之前验证您是否正确填充了L
的所有四个成员
要成功读取所有四个成员,必须首先读取第一个成员。在读取第一个成员时调整读取循环,例如:
while (getline (myfile, L.Title)) { /* validate each read */
读取第一个成员后,验证正在读取的下三个成员中的每个成员:
if (getline (myfile, L.Category) &&
myfile >> L.YOP && myfile >> L.Gross) {
v.push_back(L); /* before adding temp struct to vector */
i++;
}
假设您的输入文件中只有一个'\n'
后面的Gross
是很危险的,这会使您的读取变得脆弱。忽略行尾的所有字符,例如
/* ignore all characters to \n */
myfile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
int main (int argc, char **argv)
{
if (argc < 2) { /* validate at least 1 argument given for filename */
std::cerr << "usage: " << argv[0] << " filename\n";
return 1;
}
...
LoadMovies(v, argv[1]); /* pass filename to open to LoadMovies */
相反,在命令行上传递文件名,例如
/* ignore all characters to \n */
myfile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
int main (int argc, char **argv)
{
if (argc < 2) { /* validate at least 1 argument given for filename */
std::cerr << "usage: " << argv[0] << " filename\n";
return 1;
}
...
LoadMovies(v, argv[1]); /* pass filename to open to LoadMovies */
让SearchMovies()
在调用者中提供有意义的返回以指示成功/失败。理想情况下,您希望将实现(逻辑/计算)与接口(输出给用户)分开。如果您为SearchMovies()
提供了有意义的返回类型,则可以完全从函数中删除输出,并根据您的返回将其返回到main()
中。类型为int
的简单返回就可以了-1
表示未在库中找到,或在成功时返回向量中的索引。例如:
int SearchMovies (std::vector<video>& v, const std::string& s)
{
int i;
std::string slower (s); /* string s to lowercase */
std::transform (slower.begin(), slower.end(),
slower.begin(),
[](unsigned char c){ return std::tolower(c); });
for (i = 0; i < (int)v.size(); i++) { /* movie title to lowercase */
std::string mlower (v[i].Title);
std::transform (mlower.begin(), mlower.end(),
mlower.begin(),
[](unsigned char c){ return std::tolower(c); });
if (mlower == slower) /* compare lowercase movie and string */
return i;
}
return -1; /* if not found, return -1 (cannot be an index) */
}
然后,无论用户使用何种情况键入搜索词,您的搜索都将起作用,例如
...
Please type in what movie you want.
iron man 3
You have chosen: Iron Man 3
或
这会让你找到正确的方向。如果您遇到其他障碍,请告诉我,我很乐意进一步提供帮助。当您在调试器中运行程序时,您做了哪些观察?这是一个很好的机会,可以学习如何使用它一次运行一行程序,检查所有变量及其变化时的值,并分析程序的逻辑执行流。了解如何使用调试器是每个C++开发人员所需的技能,没有例外。在调试器的帮助下,您应该能够在这个程序以及您编写的所有未来程序中快速找到bug,而无需向任何人寻求帮助。
...
Please type in what movie you want.
iron man 3
You have chosen: Iron Man 3
...
Please type in what movie you want.
thor
You have chosen: Thor