从数据读取不起作用,但为什么呢?
好吧,我已经为这个问题苦苦挣扎了几个小时。但由于某些原因我找不到该死的错误。我真的希望你最终能帮助我。
接下来,我编写了一个程序,用户必须在其中插入一些有关他的事实。名字= vname,姓氏= nname,他的帐户= echte_kontonummer,他的Pin,程序会将其和他的信用写入文件中。不要误解我,这只是为了学习目的,我永远不会用这个进行网络钓鱼;D。
但是,该工具会将这些数据写入文件中。到目前为止还不错,但现在它应该逐行读取文件。并将文本形成我需要进一步操作的变量。
但由于某些原因,它只是读取愚蠢的随机数字和字符。
最后,这是加载文件的方法:
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
}
}
well, i've struggeling with this problem for hours. but for some reasons i can't find the damn mitstake. I really hope that u can finally help me.
following, i've written a program where the user has to insert some facts about him. first name = vname, last name=nname, his account = echte_kontonummer, his Pin and the programm will write this and his credit into the a file. don't misunderstand me, it's for learning purposes only i will never went phishing with this ;D.
However, the tool write this datas into the file. as far so good but now it should read the file line by line. and form the text into variables i need for further operations.
but for some reasons, it just read stupid randon numbers and characters.
finally here is the methode which loads a file:
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();
}
and to complete this here is the class
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();
};
btw the language is german, hope this doesn't matter.
oh yes and here is a explanation of how the loop works
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
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
上面的代码包含了您第一次读取该文件,让我们分析一下它做了什么。 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 从类中删除,它们没有理由存在,我们将在需要时创建它们。现在对于该函数,我不确切知道您的文件是如何布局的,这是根据您提供的内容进行的猜测,但类似这样:
该函数还假设该文件是正确的,因此不会进行错误检查。如果需要,您可以检查每个 getline 的返回值,例如:
如果您想检查数字转换是否有效,您将需要使用新的 C++11 函数,stoi,stoll,etc...,出错时抛出异常。如果这些不可用,还有字符串流,您可以像这样检查:
或者您可以使用 boost lexical_cast,内部使用字符串流,出错时会抛出异常。
The above code contains your first read of the file, let's analyze what it does. anrede starts out at 1, let's assume the file is full of data, so we are not near the end, so we enter the loop.
You check if anrede==1, it does, so you copy the value of inhalt_anrede(which is empty) into Anrede. So now Anrede is an empty and properly null-terminated string. Then you increment anrede. We haven't read anything from the file yet, so we of course still haven't reached eof, so we enter the loop.
Again, we check if anrede==1. It doesn't, so we execute the else portion, which gets a line from the file and stores it into inhalt_anrede. Increment anrede again, let's assume we still haven't reached eof, so we enter the loop again.
Repeat the above paragraph continuously, reading the file line-by-line and discarding the result until we have reached eof, then the loop ends. The rest of the for loops all require that we haven't reached eof. But we have reached eof, so those loops are skipped.
Since you haven't defined a default constructor, all those members are left uninitialized, which is why you see random numbers and characters.
The Fix
The first thing I do is change those char arrays in your class to std::string, because it makes my life simpler. I also remove those ifstreams from the class, there is no reason for them to be there, we will create them when we need them. Now for the function, I don't know exactly how your file is laid out, this is a guess based on what you've provided, but something like this:
The function also assumes that the file is correct and so does no error checking. If you want, you can check the return value of each getline, e.g.:
If you want to check that the numeric conversions are valid, you'll want to use something like the new C++11 functions, stoi,stoll,etc..., which throw exceptions on error. If those aren't available, there's also string streams, which you can check like this:
Or you can use boost lexical_cast, which uses string streams internally, and will throw exceptions on error.