read a text file store then write to it.

I am working on a school project where I have to create a time clock (which I have working) and store the clock in and our data in a file(which is also working). I then have to create another text file that stores the total hours working(which is working as well) now what I need to do is next time the program is launched I have to add to get the total hours worked and add the new days total hours worked to the previous, and so on. So my issue is I can not figure out how to read the total hours worked file get the hours and add it to the new days total hours worked, then write that new total hours to the same text total hours worked text file. I hope I have made myself clear on this.
How do you input the hours to that first file,
Tell us about the structure of you existing files with some diagrams please
Last edited on
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#include "pch.h"
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

struct TIME
{
	int minutes;
	int hours;
	char ch;
};



void computeTimeDifference(struct TIME, struct TIME, struct TIME *);


int main()
{
	struct TIME st, et, difference;


	string date;
	string task;

	int rhours;
	int rminutes;
	int Thours;
	int Tminutes;

	ofstream tfile;
	fstream ttfile;

	// prompts user to enter in the date and stores information in string date
	cout << "Enter the Date. (MM-DD-YY)" << endl;
	cin >> date;

	// prompts user to enter in the start time and stores information in time st
	cout << "Enter the Start Time. (HH MM A or P)" << endl;
	cin >> st.hours >> st.minutes >> st.ch;

	//checks if user entered in specific letters if not runs error code
	while (!((st.ch == 'a') || (st.ch == 'A') || (st.ch == 'p') || (st.ch == 'P')))
	{
		// Explain error
		cout << "ERROR: an A or a P must be entered: ";
		// Clear input stream
		cin.clear();
		// Discard previous input
		cin.ignore(132, '\n');
		// Receive input again
		cin >> st.hours >> st.minutes >> st.ch;
	}

	cout << "Enter the End Time. (HH MM)" << endl;
	cin >> et.hours >> et.minutes >> et.ch;

	while (!((et.ch == 'a') || (et.ch == 'A') || (et.ch == 'p') || (et.ch == 'P')))
	{
		// Explain error
		cout << "ERROR: an A or a P must be entered: ";
		// Clear input stream
		cin.clear();
		// Discard previous input
		cin.ignore(132, '\n');
		// Receive input again
		cin >> st.hours >> st.minutes >> et.ch;
	}

	cout << "Task Worked On." << endl;
	cin >> task;

	computeTimeDifference(st, et, &difference);

	cout << "Total Time:" << difference.hours << ":" << difference.minutes << endl;

	tfile.open(date.c_str());
	tfile << date << endl;
	if (st.minutes < 10)
	{
		tfile << st.hours << ":0" << st.minutes << " " << st.ch << " - ";
	}
	else
	{
		tfile << st.hours << ":" << st.minutes << " " << st.ch << " - ";
	}

	if (et.minutes < 10)
	{
		tfile << et.hours << ":0" << et.minutes << " " << et.ch << endl;
	}
	else
	{
		tfile << et.hours << ":" << et.minutes << " " << et.ch << endl;
	}
	tfile << task << endl;
	if (difference.minutes < 10)
	{
		tfile << "Total Time: " << difference.hours << ":0" << difference.minutes << endl;
	}
	else
	{
		tfile << "Total Time:" << difference.hours << ":" << difference.minutes << endl;
	}
	tfile.close();

	// opens total time text file
	ttfile.open("Total Time.txt", ios_base::out | ios_base::in);

	//checks if text file exists if not makes one and stores current total hours
	if (ttfile.is_open())
	{
		ttfile >> rhours;
		ttfile >> rminutes;

		Thours = rhours + difference.hours;
		Tminutes = rminutes + difference.minutes;

		ttfile << Thours << " " << Tminutes;


	}
	else
	{
		ttfile.clear();
		ttfile.open("Total Time.txt", ios_base::out);

		if (difference.minutes < 10)
		{
			ttfile << difference.hours  << difference.minutes;
		}
		else
		{
			ttfile << difference.hours << difference.minutes;
		}

	}

	ttfile.close();

	return 0;
}

void computeTimeDifference(struct TIME st, struct TIME et, struct TIME *difference)
{
	int StartTime = 0;
	int EndTime = 0;
	int Difference_Seconds;

	if ((st.ch == 'P' || st.ch == 'p') && st.hours != 12)
	{
		StartTime = 12 * 3600;
	}

	if ((et.ch == 'P' || et.ch == 'p') && et.hours != 12)
	{
		EndTime = 12 * 3600;
	}

	StartTime += (st.hours * 3600) + (st.minutes * 60);
	EndTime += (et.hours * 3600) + (et.minutes * 60);

	if (EndTime < StartTime)
	{
		EndTime += 24 * 3600;
	}

	Difference_Seconds = EndTime - StartTime;

	difference->hours = (double)(floor(Difference_Seconds / 3600));
	difference->minutes = (Difference_Seconds % 3600) / 60;

}


this is my entire code for the entire program.

here is the code just for the total work hours portion

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
// opens total time text file
	ttfile.open("Total Time.txt", ios_base::out | ios_base::in);

	//checks if text file exists if not makes one and stores current total hours
	if (ttfile.is_open())
	{
		ttfile >> rhours;
		ttfile >> rminutes;

		Thours = rhours + difference.hours;
		Tminutes = rminutes + difference.minutes;

		ttfile << Thours << " " << Tminutes;


	}
	else
	{
		ttfile.clear();
		ttfile.open("Total Time.txt", ios_base::out);

		if (difference.minutes < 10)
		{
			ttfile << difference.hours  << difference.minutes;
		}
		else
		{
			ttfile << difference.hours << difference.minutes;
		}

	}

	ttfile.close();
Might want to put spaces between the hours and minutes differences for the ttfile.open("total time.txt") thing at the bottom or I’m pretty sure it will take both for one int when you try to input them back in.

Just for starters.
Last edited on
I would try to tell you just reg but I’m not good at that so it’s just going to be a bunch of code and comments, ask as many questions as needed I guess 😜

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <fstream>
using namespace std;

int main(){
  int minutes;
  int hours;
  // all that sick stuff you already made that gats the right diffs
  fstream fio; // see what I did there? XD fio lol sounds like a name
  fio.open("Total Hours output file thingy"); 
  int temph; // your old hours
  int tempm; // your old minutes
  fio >> temph;
  fio >> tempm;
  temph += hours; 
  tempm += minutes;
  fio.seekp(0); // sends the 'cursor' to the start of yer file
  fio << '\n';
  fio.seekp(0); // there’s obviously better ways to do this, just trying to not mix the new with the old.
                //obviously the best thing would have been clearing the file, but I have no  idea how..
  fio << temph << ' '; // the space is so that when you get the times again they don’t both get input into only temph or something.
  fio << tempm;
}
Hello atoken,

I have been working on the code for awhile and even used some of highwayman's suggestions. The first part are some small things I found in the program.

1
2
3
cout << "Enter the Start Time. (HH MM A or P)" << endl;

cout << "Enter the End Time. (HH MM)" << endl;


They should match.

1
2
3
cout << "\n Enter the Start Time. (HH MM A or P): ";

cout << "\n Enter the End Time. (HH MM A or P): ";

The "\n " at the beginning of the string is optional. It is more for making what is sent to the display easier to read. The ": " and removing the "endl" puts the following "cin" statements on the same line as the prompt. I think it works better this way.

Also in the while loops it would help to reissue the prompt and not expect everyone who may use the program to understand what you are doing.

for this line cout << "\n Task Worked On.: ";. At first I was entering a number until I finally noticed that the variable is defined as a string. You might want to add something to the prompt to give the user an idea of what is expected. Or create a menu of choices to work from.

For the function I changed the prototype and function definition to:
void computeTimeDifference(const TIME& st, const TIME& et, TIME& difference)

By making the first two parameters a constant they can not be changed in the function. They should only be used. Since the third parameter needs to be changed it can not be a constant. I passed all three be reference. This cuts the overhead of having to make a copy of the original variables. Passing "difference" by reference means that you do not need the pointer. This keeps the code in the function from switching between "." and "->". It keps the code consistent.

In addition to making the change to the last two lines of the function I found that all you need is:
difference.hours = Difference_Seconds / 3600;. It works the same with out the warning of trying to put a "double" into an "int".

The rest of the function I did not look at closely, but it appears to work.

That should give you something to work on for awhile.

Hope that helps,

Andy
Hello atoken,

Sorry about missing the most important part as I was distracted and lost track of where I was at.

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
std::fstream ttfile("Total Time.txt", ios::in | ios::out);

//checks if text file exists if not makes one and stores current total hours
if (ttfile)
{
	ttfile.seekg(0);

	ttfile >> rhours;

	ttfile >> rminutes;

	// Figure total hours needs changed.
	// Total minutes also needs changed.

	ttfile.seekg(0);

	ttfile << Thours << " " << Tminutes;
}
else
{
	//ttfile.clear();  // <--- Not needed. If you reach here the stream did not open on the first try, so opening the stream as
					   // an "ofstream" is not a problem.
	std::ofstream ttfile("Total Time.txt");

	ttfile << difference.hours << ' ' << difference.minutes; // <--- This is all you need. Note the space.

	// <--- Do not see your point here because the if and else are exactly the same.
	//if (difference.minutes < 10)
	//{
	//	ttfile << difference.hours << ' ' << difference.minutes; // <--- Added the space.
	//}
	//else
	//{
	//	ttfile << difference.hours << ' ' << difference.minutes; // <--- Added the space.
	//}
}

ttfile.close();

Although ios_base works all you really need is ios::. No point in making extra work that you do not need.

I eventually figured how the if/else was working and that part does work.

When you open the "fstream" for output it put the file pointer at the end of the file ready to append the file. Even when you open the stream for input and output it still puts the file pointer at the end of the file.

The first line of the if section sets the file pointer to the beginning of the file so that you can read the two numbers in the file. Otherwise the file pointer is at the end of the file and the first read will set "eof" on the stream making it unusable and it will read or write nothing.

The two lines to figure total hours and minutes need to be done differently.

Hint: When figuring total hours you need to account for "rminutes" and "difference.minutes" being over 60. and when figuring total minutes you need what is left over or the remainder.

When I first started testing the program total minutes increased to over 200. Not what you want.

When you write the numbers to the file at most you will have two digits for hours an minutes. Also note fot the "Total Time.txt" file leading zeros make no difference. When the file is read and the numbers stored into an "int" any leading zeros will be dropped.

Before you write to the file again you will have to set the file pointer to the beginning.

In my testing I found that "seekg" worked and that "seekp" did not work. Then again this may just be my computer or something I am missing as I do not have the greatest experience using a "fstream" for both input and output.

The comments in the else section should explain it.

Hope that helps,

Andy
Isn’t seekg only supposed to be for input and not output?
Here is the full guide:
Create a text file in C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <fstream>
using namespace std;
int main () 
{
  ofstream file;
  file.open ("Codespeedy.txt");
  if (file.is_open())
  {
  file << "hello i am Raj gaurav.\n";
  file << "hello i am Raj gaurav2.\n";
  file.close();
  }
  else cout << "can not open a file";
  return 0;
  }

Then read line from the text file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main () 
{
  string line;
  ifstream file ("Codespeedy.txt");
  if (file.is_open())
  {
    for (int lineno = 1; getline (file,line) && lineno < 3; lineno++)
      if (lineno == 2)
          cout << line << endl;
    file.close();
  }
 else cout << "Can not open the file"; 
 return 0;

Reference: https://www.codespeedy.com/cpp-program-to-create-a-text-file-open-and-read-a-particular-line
@highwayman,


Isn’t seekg only supposed to be for input and not output?


That is the way I understand it, but when I tried using "seekp" it did not work.

Maybe it has something to do with VS or maybe works with an "ofstream"?

Andy
Topic archived. No new replies allowed.