Getting error in ofstream file.

I am writing an eVoting program the addTally function adds 1 to the Candidate's voting tally when called and prints it back to the file from where it took the input replacing the old text.
Now, I have no idea why im getting an error when running this program. Whenever i comment out the output file in addTally Function including where its used, it works. Any ideas please?

Vote Function
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
void Vote(vector<int> &id_list, ofstream &voter_list)
{
    int ID;
    bool valid_id;
    char choice;

    cout << "\t**** Voting Menu ****\n\n";
    
    cout << "Enter your ID: ";
    cin >> ID;
    
    valid_id = id_check(ID, id_list);
    
    if (valid_id == true)
    {
        voting_Menu();
        cin >> choice;
        
        switch (choice) 
        {
            case '1':
                addTally(choice);
                
                cout << "Tallied..." << endl;
                break;
            case '2':
                
                break;

            default:

                break;
        }
    }
    else
        cout << "Invalid ID..." << endl;
}


Function Adds one to the tally
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
void addTally(char choice)
{
    ifstream inCandidate("Candidates.txt");
    ofstream outCandidate("Candidates.txt");
    
    string Data_Line;
    vector <string> Candidates;
    
    string C_name[5];
    int Tally[5];
    
    
    while(getline(inCandidate, Data_Line)) //Store data read from 'inCandidate' in 'Data_Line' while "std::getline()" returns true.
    {
        Candidates.push_back(Data_Line); //Creates a TEMPORARY object that std::vector.push_back then uses the default copy operator to create and store an instance from.
        cout << Data_Line <<endl;
    }
    
    for (int i = 0; i < 2; i++)
    {
        stringstream ss(Candidates[i]);
        ss >> C_name[i] >> Tally[i];
        cout << Tally[i] << endl;
    }
    
    switch (choice) {
        case '1':
            Tally[0]++;
            outCandidate << C_name[0] << " " << Tally[0] << endl;
            outCandidate << C_name[1] << " " << Tally[1] << endl;
            break;
            
        case '2':
            Tally[1]++;
            outCandidate << C_name[0] << " " << Tally[0] << endl;
            outCandidate << C_name[1] << " " << Tally[1] << endl;
        default:
            break;
    }
    
    inCandidate.close();
    outCandidate.close();
}
Last edited on
Don't use two objects on the same file, you will have concurrency problems. Instead, use a single object and read/write that.

You should realise that you can't edit lines in a text files like that as changing the length of lines overwrites the following line. You can only treat binary files in that way.

If you want to update the text file, you need to read the content into memory, make your amendments, then rewrite the entire file.
I tried ios::in | ios::out in an object to read and write in a file but still it wont work.
I'm not changing any text in a file, as you said, i am copying the content into array, amending it and then rewriting the whole content of the file. Still its not working
I'm not changing any text in a file, as you said, i am copying the content into array, amending it and then rewriting the whole content of the file.
Can you post the update code?
Its almost the same code... I just changed ifstream to fstream and included ios in and out into it...
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
void addTally(char choice)
{
    fstream File("Candidates.txt", ios::in | ios::out);
    
    string Data_Line;
    vector <string> Candidates;
    
    string C_name[5];
    int Tally[5];
    
    
    while(getline(File, Data_Line)) //Store data read from 'inCandidate' in 'Data_Line' while "std::getline()" returns true.
    {
        Candidates.push_back(Data_Line); //Creates a TEMPORARY object that std::vector.push_back then uses the default copy operator to create and store an instance from.
        cout << Data_Line <<endl;
    }
    
    for (int i = 0; i < 2; i++)
    {
        stringstream ss(Candidates[i]);
        ss >> C_name[i] >> Tally[i];
        cout << Tally[i] << endl;
    }
    
    switch (choice) {
        case '1':
            Tally[0]++;
            File << C_name[0] << " " << Tally[0] << endl;
            File << C_name[1] << " " << Tally[1] << endl;
            break;
            
        case '2':
            Tally[1]++;
            File << C_name[0] << " " << Tally[0] << endl;
            File << C_name[1] << " " << Tally[1] << endl;
        default:
            break;
    }
    
    File.close();
}

It shows the following code when i run the program. I guess its from somewhere in C++ library. If you understand, it might help... It highlights __str_ = __s;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
template <class _CharT, class _Traits, class _Allocator>
void
basic_stringbuf<_CharT, _Traits, _Allocator>::str(const string_type& __s)
{
    __str_ = __s;
    __hm_ = 0;
    if (__mode_ & ios_base::in)
    {
        __hm_ = const_cast<char_type*>(__str_.data()) + __str_.size();
        this->setg(const_cast<char_type*>(__str_.data()),
                   const_cast<char_type*>(__str_.data()),
                   __hm_);
    }
    if (__mode_ & ios_base::out)
    {
        typename string_type::size_type __sz = __str_.size();
        __hm_ = const_cast<char_type*>(__str_.data()) + __sz;
        __str_.resize(__str_.capacity());
        this->setp(const_cast<char_type*>(__str_.data()),
                   const_cast<char_type*>(__str_.data()) + __str_.size());
        if (__mode_ & (ios_base::app | ios_base::ate))
            this->pbump(__sz);
    }
}
Last edited on
I've not tried to compile it, but your code should look something like this.
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
void addTally(char choice)
{
	struct Vote
	{
		string C_name;
		int Tally;
	};

	// Read file
	vector<string> candidates;
	{
		ifstream File("Candidates.txt");
		string Data_Line;
		while (getline(File, Data_Line)) //Store data read from 'inCandidate' in 'Data_Line' while "std::getline()" returns true.
		{
			candidates.push_back(Data_Line); //Creates a TEMPORARY object that std::vector.push_back then uses the default copy operator to create and store an instance from.
			cout << Data_Line <<endl;
		}
	}

	// Read into structure
	vector<Vote> votes;
	for (size_t i = 0; i != candidates.size(); ++i)
	{
		istringstream ss(Candidates[i]);
		Vote vote;
		ss >> vote.C_name >> vote.Tally;
		votes.push_back(vote);

		cout << vote.Tally << endl;
	}

	// Update vote
	size_t idx = choice - '1';
	votes.at(idx).Tally++;

	// Rewrite file
	{
		ofstream File("Candidates.txt", ios::trunc);
		for (size_t i = 0; i != votes.size(); ++i)
		{
			File << votes[i].C_name << ' ' << votes[i].Tally << endl;
		}
	}
}
Last edited on
Topic archived. No new replies allowed.