How to read a file line by line without the getline function?

Pages: 12
Hello, so I am trying to read a .txt file with this information:

Ann Perkins
217 Lowell Drive
Pawnee
IN
47408
3
4.2

Ron Swanson
3657 White Bridge Road
Eagleton
IN
47320
2
2.3

Andy Dwyer
789 Cherry Road
Wamapoke
IN
48034
1
1.8

My program is supposed to create a mailing label for each mailing in the file. Although there are three mailings in the file, my program must be able to work with any number of mailings. I've already created a while loop, so that it'll read till the end of file, but I don't know how to manipulate it to where its in this layout:

Ann Perkins
217 Lowell Drive
Pawnee IN 47408

So, what I feel like I have to do is to read the file line by line and store each line into different variables. I tried researching online and through my textbook, and the answer that I'm seeing the most is the getline function. However, I can't use that function because it has not been covered yet, and I can't use anything that we haven't covered yet in this project. So, my question is how can read the file line by line and store it into variables WITHOUT using the getline function. Any help would be greatly appreciated!

This is what I have so far, minus all the math algorithms and other variables needed to create the barcode and shipping cost.


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
  #include <iostream>
#include <fstream>
#include <string>
using namespace std;



int main()
{
	ifstream inputFile;
	string line;
	
	inputFile.open("Mailings file.txt");
	
	while (inputFile >> line)
	{
		cout << line << endl;
	}
	
	inputFile.close();



	return 0;
}


Roll your own. For example:
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
#include <iostream>
#include <string>

using std::string;
using std::cin;
using std::cout;
using std::istream;

istream & getLine(istream &is, string &result, char delim = '\n')
{
    char ch;
    result.clear();
    while (is.get(ch)) {
        if (ch == delim) {
            break;
        } else {
            result += ch;
        }
    }
    return is;
}


int main()
{
    string line;
    while (getLine(cin, line)) {
        cout << "line: " << line << '\n';
    }
}

Thanks for the reply! I see what you mean by rolling my own. Unfortunately, I can't use the result.clear(); function because that has not been covered yet. I really can't use anything advanced; otherwise, I'd have no problem doing this program. The furthest topics that we've covered that is allowed for this project are the nested loops, the very beginnings of inputting and outputting a file, if/else, and really beginner type stuff.
result.clear(); is not a big deal. result is a std::string. An equivalent is result = "";

As for your question, a line is identified by the newline character '\n'. Construct the code in any way you like, but you will need to be able to identify that, presumably by reading one character at a time.
I'm sorry, I'm so confused. How do I go about in reading one character at a time, if I put the file into a while loop, so that it'll read everything in the file no matter how many mailers? I can read and store each word or number into its own variable, but that's not what the project is asking me to do.

For example, I could do it this way, but it would be wrong because it doesn't account for the possibility of other mailers being put into the file.
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
#include <iostream>
#include <fstream>
#include <string>
using namespace std;



int main()
{
	ifstream inputFile;
	
	string name1, name2, name3, name4, name5, name6, name7, name8, name9, name10,
		   street_number1, street_number2, street_number3, street_number4, street_number5,
		   street1, street2, street3, street4, street5, street6, street7, street8, street9, street10, street11,
		   city1, city2, city3, city4, city5,
		   state1, state2, state3, state4, state5,
		   zipcode1, zipcode2, zipcode3, zipcode4, zipcode5,
		   num1, num2, num3, num4, num5,
		   weight1, weight2, weight3, weight4, weight5;   
	
	
	inputFile.open("Mailings.txt");
	
	// Ann Perkins
	inputFile >> name1;
	inputFile >> name2;
	inputFile >> street_number1;
	inputFile >> street1;
	inputFile >> street2;
	inputFile >> city1;
	inputFile >> state1;
	inputFile >> zipcode1;
	inputFile >> num1;
	inputFile >> weight1;
	
	// Ron Swanson
	inputFile >> name3;
	inputFile >> name4;
	inputFile >> street_number2;
	inputFile >> street3;
	inputFile >> street4;
	inputFile >> street5;
	inputFile >> city2;
	inputFile >> state2;
	inputFile >> zipcode2;
	inputFile >> num2;
	inputFile >> weight2;
	
	// Andy Dwyer
	inputFile >> name5;
	inputFile >> name6;
	inputFile >> street_number3;
	inputFile >> street6;
	inputFile >> street7;
	inputFile >> city3;
	inputFile >> state3;
	inputFile >> zipcode3;
	inputFile >> num3;
	inputFile >> weight3;
	
	// Ben Wyatt
	inputFile >> name7;
	inputFile >> name8;
	inputFile >> street_number4;
	inputFile >> street8;
	inputFile >> street9;
	inputFile >> city4;
	inputFile >> state4;
	inputFile >> zipcode4;
	inputFile >> num4;
	inputFile >> weight4;
	
	// Chris Traeger
	inputFile >> name9;
	inputFile >> name10;
	inputFile >> street_number5;
	inputFile >> street10;
	inputFile >> street11;
	inputFile >> city5;
	inputFile >> state5;
	inputFile >> zipcode5;
	inputFile >> num5;
	inputFile >> weight5;
	
	// Ann
	cout << name1 << " " << name2 << endl << street_number1 << " " << street1 << " " << street2 << endl
	<< city1 << " " << state1 << " " << zipcode1 << endl << endl;
	
	// Ron
	cout << name3 << " " << name4 << endl << street_number2 << " " << street3 << " " << street4 << " " << street5 << endl
	<< city2 << " " << state2 << " " << zipcode2 << endl << endl;
	
	// Andy
	cout << name5 << " " << name6 << endl << street_number3 << " " << street6 << " " << street7 << endl
	<< city3 << " " << state3 << " " << zipcode3 << endl << endl;
	
		
	// Ben
	cout << name7 << " " << name8 << endl << street_number4 << " " << street8 << " " << street9 << endl
	<< city4 << " " << state4 << " " << zipcode4 << endl << endl;
	
	// Chris
	cout << name9 << " " << name10 << endl << street_number5 << " " << street10 << " " << street11 << endl
	<< city5 << " " << state5 << " " << zipcode5 << endl << endl;
	

return 0;
}
I'm afraid we don't know what you have been taught, so how can we advise you ?

Maybe if you look in the book for a option to read a line that you have studied the answer will come to you.

I've already looked in the book. There is nothing about reading a line in the chapters that we have covered. The getline function for inputting a file is something that we have not gone over yet, so I can't use that in my program. The only topics that are covered pertaining to inputting and outputting a file, is reading it byte by byte.
cpchang10491

I'm in that class and doing the same problem.

You've got to use
1
2
3
4
5
6
7
                                getline(mailingList, name);
                                getline(mailingList, street);
	                        getline(mailingList, city);
				getline(mailingList, state);
				mailingList >> zip;
				mailingList >> package;
				mailingList >> weight;

and that will get you each line to be stored. I used mailingList instead of inputFile.
However, I can't get the program to read "Ann" from the first name when I'm reading the file while running the real program. I've even tried this:

1
2
3
4
5
6
7
8
                      cin.ignore();
                                getline(mailingList, name);
				getline(mailingList, street);
				getline(mailingList, city);
				getline(mailingList, state);
				mailingList >> zip;
				mailingList >> package;
				mailingList >> weight;

and I get all the lines, package choice and weight info just not "Ann"
Hey there! Yea, I saw that from other forums, but are we allowed to use that getline function? The rubric says we can only use concepts covered in chapters 1-5, but that function isn't until chapter 12.
And as for not covering it in the book, I don't know how our teacher would expect us to get it done any other way. We have used the getline command, we just needed to figure out how to make it work in this context. I'm using it.

I can get my file to loop but I still can't get it to read/record the first name of all the entries. The program spits everything out like it's supposed to but with last names only. I made a do/while loop and it will now read the first first name , "Ann", but won't read any other first name.
1
2
3
4
5
6
7
8
9
                       do
			{
				getline(mailingList, name);
				getline(mailingList, street);
				getline(mailingList, city);
				getline(mailingList, state);
				mailingList >> zip;
				mailingList >> package;
				mailingList >> weight;


1
2
3
4
5
6
7
8
9
10
11
				//This section displays information from the file. 
				cout << "\n";
				cout << left << "**********************************$";
				cout << postage << "\n";
				cout << name << "\n";
				cout << street << "\n";
				cout << city << ", " << state << " " << zip << "\n";
				cout << "|" << bar10k << bar1k << bar100 << bar10 << bar1 << barcheck << "|";
				cout << "\n\n";
			}//Last bracket for reading mailing list
			while (mailingList >> name);


So that's my code, minus the stuff in the middle. So by putting the while at the end of the block the program will read Ann's name and all of her info but skips everybody elses first names. I can't figure out how to get it to test in the while loop but retain the info it reads. It seems to me that when it tests (while a value is getting stored to name) it takes in the first name, returns true, then only remembers the last name. What am I missing?
Last edited on
Yea, we've used the getline command for cin only though, not file streams. I was just afraid of getting a 0, but I am really starting to think this is the only way.
I'm re-writing my code to use the getline function. I'll see if I have the same problems.
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
#include <iostream>
#include <fstream>
#include <string>
using namespace std;



int main()
{
	string line;
	fstream inputFile;
	string name, street, city, state;
	string zipcode, num;
	string weight;
	
	inputFile.open("Mailings.txt");
	
if (inputFile)
{
	while (inputFile >> line)
	{
	getline(inputFile, name);
	getline(inputFile, street);
	getline(inputFile, city);
	getline(inputFile, state);
	getline(inputFile, zipcode);
	getline(inputFile, num);
	getline(inputFile, weight);
	
	cout << name << endl << street << endl << city << " " << state << " " << zipcode << endl;
	}

	
}



	
	

	

return 0;
}


I got this so far, and I'm not getting any first names
Any idea on how to calculate the total cost of all the postage in the text file as well? I believe we have to use a running total, but I don't know how to add up all the postage for all the mailings in the text file.
I think you're taking the instructions too literally:
The rubric says we can only use concepts covered in chapters 1-5
That doesn't say that you must have covered every method and every construct before you can use them. If you've covered cin/cout then you've covered the concept of streams and I think you can use fstream. If you've learned about std::string then you can use any method or function that uses it.

Any idea on how to calculate the total cost of all the postage in the text file as well?

Something like:
1
2
3
4
5
double sum = 0.0;
while (inputfile >> line) {
    ...
    sum ++ postageForThisItem;
}

I got this so far, and I'm not getting any first names
The names are in the line variable because you read it here:
while (inputFile >> line)

You should break out of the loop if you fail to read the entire record. You could do this with a comma operator in the while loop:
while (getline(inputFile, name),
getline(inputFile, street),
getline(inputFile, city),
getline(inputFile, state),
getline(inputFile, zipcode),
getline(inputFile, num),
getline(inputFile, weight)) {
...
}

That's a little unusual, so it might be easier to read if you break from the middle of the loop:
1
2
3
4
5
6
7
8
9
10
11
12
13
while (true) {
	getline(inputFile, name);
	getline(inputFile, street);
	getline(inputFile, city);
	getline(inputFile, state);
	getline(inputFile, zipcode);
	getline(inputFile, num);
	getline(inputFile, weight);

	if (!inputFile) break;

	...
}
Yeah I agree with dhayden. We've covered getline and cin and now file streams so I think its a natural progression to join these concepts together and write code. I think what the instructions to only use concepts covered in 1-5 (which getline was covered in) means that you can't use multiple functions in Project 3 from Chapter 6 as an example.

A question: in this line
while (inputfile >> line)
is line a variable or does that mean true while a "line" is read and stored? Following the motion of a cin >> variable statement? I'm not sure what I'm reading there and want to be clear.

I'm going to try the break thing. I would never have thought of that. Thank God I came back and read this. I forgot about a total shipping for choice 2.
Last edited on
A question: in this line
while (inputfile >> line)


line is a variable - from the name we might assume it is a std::string. However the >> operator works with multiple different types such as int, double, char and so on, hence line does not have to be a string.

That is really just a different syntax for calling a function. So it is calling a function which takes two parameters, the stream inputfile and the variable line. The function will attempt to read an item of the same type as line from the stream, and store it in the variable.

In addition, the function will have a return value, in this case it returns a reference to the stream. You know you can test a stream like this:
if (!inputFile) break;

So you might do something like this:
1
2
inputfile >> line;
if (inputfile) { // do something } 


Here the 'do something' is executed only if the previous operation on the stream was successful. But you can also combine those two statements like this:
1
2
if (inputfile >> line)
    { // do something } 
with the same effect.

So - back to the original question, that while statement is saying, first try to extract a value from the stream into the variable. Then test the stream to see whether the operation was successful, and if it was, enter the body of the loop and carry out the instructions there.

And yes, it is the same as a cin >> variable statement, both cin and inputfile are input streams and can be treated almost identically
Last edited on
Yea, talked with the professor, and getline is OK to use. So, I tried the break thing as well, but it's only printing out one mailer instead of all of them in the file. Here is my code:

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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
	else if (choice == multiple_mailing)
	{
		// string the line and place into while loop, so the entire file will be read
		
		fstream inputFile;
		// opening the file
		inputFile.open("Mailings.txt");
		
		while (true)
		{
			// read the file line by line and store it into appropriate variables 
			getline (inputFile, name);
			getline(inputFile, street);
			getline(inputFile, city);
			getline(inputFile, state);
			inputFile >> zipcode;
			inputFile >> num;
			inputFile >> weight;
			
			if (!inputFile) break;
		
	
			// create check digit
			n1 = zipcode % 10;
			r1 = zipcode / 10;
			n2 = r1 % 10;
			r2 = r1 / 10;
			n3 = r2 % 10;
			r3 = r2 / 10;
			n4 = r3 % 10;
			r4 = r3 / 10;
			
			total = n1 + n2 + n3 + n4 + r4;
			checkDigit = 10 - (total % 10);     		  
	
			// create if statements for mailing type and display output accordingly
			if (num == 1)
			{
				if (weight > 1)
				{
					new1 = price1 + (charge1 * (weight-1));
					cout << "\n\n***********************************$"<< setprecision(2) << fixed << new1 << endl << endl << name << endl << street << endl << city; 
					cout << "   " << state << " " << zipcode << endl << endl;
				}
				else
				{
					cout << "\n\n***********************************$0.49" << endl << endl << name << endl << street << endl << city; 
					cout << "   " << state << " " << zipcode << endl << endl;
				} 
			}
			else if (num == 2)
			{
				if (weight > 1)
				{
					new2 = price2 + (charge1 * (weight-1));
					cout << "\n\n***********************************$"<< setprecision(2) << fixed << new2 << endl << endl << name << endl << street << endl << city; 
					cout << "   " << state << " " << zipcode << endl << endl;
				}
				else 
				{
					cout << "\n\n***********************************$0.98" << endl << endl << name << endl << street << endl << city; 
					cout << "   " << state << " " << zipcode << endl << endl;
				}
			}
			else if (num == 3)
			{
				if (weight > 3)
				{
					new3 = price3 + (charge2 * (weight - 3));
					cout << "\n\n***********************************$"<< setprecision(2) << fixed << new3 << endl << endl << name << endl << street << endl << city; 
					cout << "   " << state << " " << zipcode << endl << endl;	
				}
				else
				{
					cout << "\n\n***********************************$2.54" << endl << endl << name << endl << street << endl << city; 
					cout << "   " << state << " " << zipcode << endl << endl;
				}
				
			}
			// switch statements to generate barcode
				switch (r4)                                  
			{
				case 1: cout << "|:::||";
				break;
				case 2: cout << "|::|:|";
				break;
				case 3: cout << "|::||:";
				break;
				case 4: cout << "|:|::|";
				break;
				case 5: cout << "|:|:|:";
				break;
				case 6: cout << "|:||::";
				break;
				case 7: cout << "||:::|";
				break;
				case 8: cout << "||::|:";
				break;
				case 9: cout << "||:|::";
				break;
				case 0: cout << "|||:::";
				break;
			}
			switch (n4)
			{
				case 1: cout << ":::||";
				break;
				case 2: cout << "::|:|";
				break;
				case 3: cout << "::||:";
				break;
				case 4: cout << ":|::|";
				break;
				case 5: cout << ":|:|:";
				break;
				case 6: cout << ":||::";
				break;
				case 7: cout << "|:::|";
				break;
				case 8: cout << "|::|:";
				break;
				case 9: cout << "|:|::";
				break;
				case 0: cout << "||:::";
				break;
			}
			switch (n3)
			{
				case 1: cout << ":::||";
				break;
				case 2: cout << "::|:|";
				break;
				case 3: cout << "::||:";
				break;
				case 4: cout << ":|::|";
				break;
				case 5: cout << ":|:|:";
				break;
				case 6: cout << ":||::";
				break;
				case 7: cout << "|:::|";
				break;
				case 8: cout << "|::|:";
				break;
				case 9: cout << "|:|::";
				break;
				case 0: cout << "||:::";
				break;
			}
			switch (n2)
			{
				case 1: cout << ":::||";
				break;
				case 2: cout << "::|:|";
				break;
				case 3: cout << "::||:";
				break;
				case 4: cout << ":|::|";
				break;
				case 5: cout << ":|:|:";
				break;
				case 6: cout << ":||::";
				break;
				case 7: cout << "|:::|";
				break;
				case 8: cout << "|::|:";
				break;
				case 9: cout << "|:|::";
				break;
				case 0: cout << "||:::";
				break;
			}
			switch (n1)
			{
				case 1: cout << ":::||";
				break;
				case 2: cout << "::|:|";
				break;
				case 3: cout << "::||:";
				break;
				case 4: cout << ":|::|";
				break;
				case 5: cout << ":|:|:";
				break;
				case 6: cout << ":||::";
				break;
				case 7: cout << "|:::|";
				break;
				case 8: cout << "|::|:";
				break;
				case 9: cout << "|:|::";
				break;
				case 0: cout << "||:::";
				break;
			}
			switch (checkDigit)                         
			{
				case 1: cout << ":::|||";
				break;
				case 2: cout << "::|:||";
				break;
				case 3: cout << "::||:|";
				break;
				case 4: cout << ":|::||";
				break;
				case 5: cout << ":|:|:|";
				break;
				case 6: cout << ":||::|";
				break;
				case 7: cout << "|:::||";
				break;
				case 8: cout << "|::|:|";
				break;
				case 9: cout << "|:|::|";
				break;
				case 0: cout << "||:::|";
				break;
			}
		}
	}


Even if I put it into a if (inputFile) loop, I am still getting the same result.
Last edited on
Its only printing one mailer because it's only reading one. That's because you need to read and discard the blank line between entries.
I've tried a bunch of stuff too, just not the right stuff. I can not get the proper data out of the file. I get "Ann Perkins" and all of her data but the rest of the entries are missing the first names. I've tried using cin.ignore and if (inputFile >> line) and if (!inputFile) break; and I've put only commas after the file-read-into-variable lines of code. Nothing is working for me.
Pages: 12