接下来,我写了一个程序,用户必须插入一些关于他的事实。 first name = vname,last name = nname,他的account = echte_kontonummer,他的Pin和programm会把这个和他的信用写入一个文件。不要误解我,这只是为了学习目的,我永远不会用这种方式进行网络钓鱼; D。
但是,该工具会将此数据写入文件。虽然这么好但现在它应该逐行读取文件。并将文本形成我需要进一步操作的变量。
但由于某些原因,它只是读取了愚蠢的randon数字和字符。
最后这里是加载文件的方法:
void Kunde::laden(){
string inhalt_anrede, inhalt_vname, inhalt_nname, inhalt_knummer, inhalt_pin, inhalt_guthaben;
int anrede, vorname, nachname, knummer, pin, guthaben;
system("cls");
cout << "wie ist ihr nachname?" << endl;
cin >> nname;
user1.open(nname, ios::in);
if(!user1.is_open()){
cout << "Datei nicht gefunden" << endl;
}
if(user1.is_open()){
for ( anrede=1;!user1.eof();anrede++){
if (anrede==1){
strcpy(Anrede,inhalt_anrede.c_str());
}
else
getline(user1, inhalt_anrede);
}
for ( vorname=1;!user1.eof();vorname++){
if (vorname==2){
strcpy(vname,inhalt_vname.c_str());
}
else
getline(user1, inhalt_vname);
}
for ( nachname=1;!user1.eof();nachname++){
if (nachname==3){
strcpy(nname,inhalt_nname.c_str());
}
else
getline(user1, inhalt_nname);
}
for ( knummer=1;!user1.eof();knummer++){
if (knummer==4){
echte_kontonummer=atol(inhalt_knummer.c_str());
}
else
getline(user1, inhalt_knummer);
}
for ( pin=1;!user1.eof();pin++){
if (pin==5){
echte_pin=atoi(inhalt_pin.c_str());
}
else
getline(user1, inhalt_pin);
}
for ( guthaben=1;!user1.eof();guthaben++){
if (guthaben==6){
Guthaben=atoi(inhalt_guthaben.c_str());
}
else
getline(user1, inhalt_guthaben);
}
cout << "Daten erfolgreich geladen." << endl;
cout << vname << " " << nname << " " << echte_kontonummer << " " << echte_pin << " " << Guthaben << endl;
}
user1.close();
}
并在此处完成此课程
class Kunde{
private:
char Anrede[5];
char vname[20];
char nname[20];
long long echte_kontonummer;
int echte_pin;
int Guthaben;
fstream user;
ifstream user1;
public:
void einpflegen();
void login();
void einzahlen();
void speichern();
void laden();
void zeige_guthaben();
};
不管语言是德语,希望这没关系。
哦,是的,这是对循环如何工作的解释
for ( int guthaben=1;!user1.eof();guthaben++){ //i think this is understandable
if (guthaben==4){ //in this case the desired value is on line 4 (the account number.
getline(user1, inhalt_guthaben);
echte_kontunummer=atol(inhalt_knummer.c_str()); //from string to int to the desired value Guthaben. here foe e.g i only get random numbers when the console should put out this value
}
}
答案 0 :(得分:2)
for ( anrede=1;!user1.eof();anrede++){
if (anrede==1){
strcpy(Anrede,inhalt_anrede.c_str());
}
else
getline(user1, inhalt_anrede);
}
上面的代码包含您对该文件的第一次读取,让我们分析它的作用。 anrede从1开始,让我们假设文件已经满了数据,所以我们还没有接近结束,所以我们进入循环。
你检查anrede == 1是否确实如此,所以你将inhalt_anrede(为空)的值复制到Anrede中。所以现在Anrede是一个空的,正确的以null结尾的字符串。然后你增加anrede。我们还没有从文件中读取任何内容,所以我们当然还没有达到eof,所以我们进入循环。
再次,我们检查anrede == 1。它没有,所以我们执行else部分,它从文件中获取一行并将其存储到inhalt_anrede中。再次增加anrede,让我们假设我们还没有达到eof,所以我们再次进入循环。
连续重复上面的段落,逐行读取文件并丢弃结果直到我们达到eof,然后循环结束。其余的for循环都要求我们没有达到eof。但是我们已经达到了eof,所以跳过了这些循环。
由于您尚未定义默认构造函数,因此所有这些成员都保持未初始化状态,这就是您看到随机数字和字符的原因。
修复
我要做的第一件事就是将类中的char数组更改为std :: string,因为它使我的生活更简单。我也从班级中删除了那些ifstreams,没有理由让他们在那里,我们会在需要时创建它们。现在对于这个功能,我不确切知道你的文件是如何布局的,这是基于你提供的内容的猜测,但是像这样:
void Kunde::laden(){
string temp;
system("cls");
cout << "wie ist ihr nachname?" << endl;
cin >> nname;
ifstream user1(nname);
if(!user1.is_open()){
cout << "Datei nicht gefunden" << endl;
return;
}
getline(user1,Anrede);
getline(user1,vname);
getline(user1,nname);
getline(user1,temp);
echte_kontonummer = atol(temp.c_str());
getline(user1,temp);
echte_pin = atoi(temp.c_str());
getline(user1, temp);
Guthaben = atoi(temp.c_str());
cout << "Daten erfolgreich geladen." << endl;
cout << vname << " " << nname << " " << echte_kontonummer << " " << echte_pin << " " << Guthaben << endl;
}
该函数还假定文件正确,因此没有错误检查。如果需要,您可以检查每个getline的返回值,例如:
if (!getline(user1,Anrede)) {
// handle error somehow
}
如果要检查数字转换是否有效,您将需要使用新的C ++ 11函数stoi,stoll,etc...,它会在出错时抛出异常。如果这些不可用,那么还有字符串流,你可以这样检查:
istringstream iss(temp);
if (!(iss >> echte_kontonummer)) {
// handle error somehow
}
或者您可以使用boost lexical_cast,它在内部使用字符串流,并会在出错时抛出异常。