Error reading a file ( i think )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//  Euromilhoes v.01

#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <iomanip>
using namespace std;

// VARIAVEIS GERAIS

void menus(),Novomembro()/*Sorteios()*/,CarregarFicheiros(),AtualizarFicheiros(),limpar();
struct membros {
        string NomePro;
        string Apelido;
        unsigned long ID;
};
vector<membros> dados;

// FIM DAS VARIAVEIS

void limpar(){

        cout << string(100,'\n');
}

int main()
{
        CarregarFicheiros();
        menus();
        AtualizarFicheiros();
}

void menus() {

        string stringTemp;
        bool variavel=false;

do {
        cout << setw(40) << "*+*EUROMILHOES _ GESTOR*+*" << endl;
        cout << "---------" << endl << "1. Registar Utilizador" << endl<< "2. Ultimos sorteios" << endl <<  "3. Sair" << endl << "---------" << endl << "R: ";
        getline(cin,stringTemp);

        if ( stringTemp == "1")
                return Novomembro();
        //if (stringTemp == "2")
          //  return Sorteios();
        if  ( stringTemp == "3")
                return;

}
        while( variavel == false);
}

void Novomembro() {

        string stringTemp;
        membros novo;
        limpar();
        //
        cout << setw(40) << "*+*EUROMILHOES _ GESTOR*+*" << endl;
        cout << setw(30) << "REGISTO"<< endl;
        cout << "---------" << endl;
        cout << "Nome proprio: ";
        getline(cin,stringTemp);
        cout << endl;
        novo.NomePro=stringTemp;
        cout << "Ultimo Nome: ";
        getline(cin,stringTemp);
        cout << endl;
        novo.Apelido=stringTemp;
        novo.ID = dados.size();
        //

        dados.push_back(novo);
        limpar();
        return menus();
}

void CarregarFicheiros(){

        string stringTemp;
        ifstream Users;
        membros carregar;

        if( Users.is_open())
        {
                getline(Users,stringTemp);

                for (unsigned int i = 0; Users.eof(); i++)
                {
                        getline(Users,stringTemp);
                        carregar.ID = stoi(stringTemp.substr(0, 7));
                        carregar.NomePro=stringTemp.substr(10,30);
                        carregar.Apelido=stringTemp.substr(35,55);
                        dados.push_back(carregar);
                }
                Users.close();
        }
        else
        {
                ofstream Users;
                Users.open("Users.txt");
                Users << setw(7) << " ID" << setw(22) << "NOME PROPRIO" << setw(20) << "APELIDO" << endl;
                Users.close();
        }
}

void AtualizarFicheiros(){

        ofstream Users;

        Users.open("Users.txt");

        Users << setw(7) << " ID" << setw(22) << "NOME PROPRIO" << setw(20) << "APELIDO" << endl;

        for(unsigned int i = 0; i < dados.size();i++)
        {

                Users << setw(7) << setfill('0') << dados[i].ID + 1 << "   " << setw(20)<< setfill(' ') << dados[i].NomePro << "   " << setw(20) << setfill(' ') << dados[i].Apelido << endl;

        }
}


So i know that if i register someone "Registar" in program, a text file will be created with a ID ( 0000001) e.g and two names. The first one and the last one. However, when i close the program and repeat the same - register a member- the others are erased and replaced by new ones. I have almost 100% sure that i am not reading correctly from the text file but i dont see where the error(s) are.

The text file is something like this:
1
2
3
4
5
      ID          NOME PROPRIO             APELIDO
0000001                  james                   gsvg
0000002                  harry                 Potter
0000003                    Sam                 goblin
0000004             Hermione              granger
Last edited on
There are a few problems in this code.
File is never actually opened:
83
84
85
86
        ifstream Users;
        membros carregar;

        if( Users.is_open())


Here the loop wil execute only when eof() is true.
90
91
92
                for (unsigned int i = 0; Users.eof(); i++)
                {
                        getline(Users,stringTemp);

Replace it with this:
1
2
    while (getline(Users,stringTemp))
    {


Line 77: return menus(); - no need for this. The menus() function already has its own loop, it doesn't need to be called more than once. There is no need to use return in function menus()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void menus() 
{
    string stringTemp;
    bool variavel=false;

    do {
        cout << setw(40) << "*+*EUROMILHOES _ GESTOR*+*" << endl;
        cout << "---------" << endl 
             << "1. Registar Utilizador" << endl
             << "2. Ultimos sorteios" << endl 
             << "3. Sair" << endl 
             << "---------" << endl << "R: ";
        getline(cin,stringTemp);

        if ( stringTemp == "1")
            Novomembro();
        //if (stringTemp == "2")
          //  Sorteios();
        if  ( stringTemp == "3")
            variavel = true;

    } while ( variavel == false);
}


Possibly there are other issues, but this should be enough to be going on with.

One comment, rather than using a fixed-width column layout in the file, you might consider delimiting each column using a character such as tab '\t' or even a comma.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void CarregarFicheiros(){
    
    string stringTemp;
    ifstream Users;
    membros carregar;
    Users.open("Users.txt");
    
    if( Users.is_open())
    {
        getline(Users,stringTemp);  // Ignorar Primeira linha
        
        while( getline(Users,stringTemp))
        {
            getline(Users,stringTemp);
            carregar.ID = stoi(stringTemp.substr(0, 6));
            carregar.NomePro=stringTemp.substr(10,30);
            carregar.Apelido=stringTemp.substr(35,55);
            dados.push_back(carregar);
        }
        
        Users.close();
    }
    if (Users.fail()) {
        
        ofstream Users1;
        Users1.open("Users.txt");
        Users1 << setw(7) << " ID" << setw(22) << "NOME PROPRIO" << setw(20) << "APELIDO" << endl;
        Users1.close();
    }
}


I did it already. Thanks. if u need , here is the solution.
Last edited on
I think eof() is corect.

But did you test it, and does the test demonstrate whether or not it is so?

More importantly, there is no check for the success or failure of the getline() before making use of stringTemp.
1
2
3
4
5
6
7
8
        while( getline(Users,stringTemp))
        {
            getline(Users,stringTemp); // Not Needed
            carregar.ID = stoi(stringTemp.substr(0, 6));
            carregar.NomePro=stringTemp.substr(10,30);
            carregar.Apelido=stringTemp.substr(35,55);
            dados.push_back(carregar);
        }

That has an error, the geline inside the loop is not required as it is already done within the loop condition.
Last edited on
Topic archived. No new replies allowed.