Reading from a file?

Hello. I'm experimenting with this simple two programs to see how the "read and write to files" works. Ok, the first part makes sense, I put a few numbers and a string into the new file I make. But the second part, if you look below...

Write to file "test"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <fstream>
using namespace std;

int main () {
	ofstream out("test");
	if(!out) {
		cout << "Cannot open file.\n";
		return 1;
	}

	out << 10 << " " << 123.23 << "\n";
	out << "This is a short text file.";

	out.close();
	return 0;
}


Ok, the second part I don't fully understand. The compiler knows exactly what part of the file belongs to a certain type of variable? I thought all the whitespaces and \n's would pose a problem. And why do I need a char variable assigned to display the string properly? I'm just a little confused and it'll be great if someone can explain me how this works...

What interests me the most is this part:
in >> i;
in >> f;
in >> ch;
in.get(str,40);

Read from file "test"
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>
using namespace std;

int main() {
	char ch;
	int i;
	float f;
	char str[80];

	ifstream in("test");
		if(!in) { cout << "Cannot open file.\n";
	return 1;
	}

	in >> i;
	in >> f;
	in >> ch;
	in.get(str,40); //Originally it was written "in>>str"

	cout << i << " " << f << " " << ch << "\n"; // but then only
	cout << str ; // the first word of the string would show up
	in.close();
	return 0;
}


This is what I get:
10 123.23 T
his is a short text file.


Cheers, Fission
Last edited on
The compiler knows exactly what part of the file belongs to a certain type of variable?

No, but thats the type of values the program will expect to extract. The reason you are getting output like that is because you are extracting one char before you're extracting a string. That char is being given the value of the first letter of the string - 'T'.

EDIT* Sorry i forgot to answer the second question. The >> operators stop taking input at the first white-space they encounter therefore they cannot be used to extract strings. Its the same in programs that take user-input, for example:

1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
   char str[80];
   
   std::cout << "Please enter your full name: ";
   cin >> str;

   // user types "mcleano rules"
   // but only "mcleano" gets extracted

   return 0;
}
Last edited on
Hello mcleano. Adittional question. Why is it imperative to assign the first letter of the string to a char variable? See if I rewrite the second program like below(I leave out the "ch" part) i get this:
10 123.23

As you can see the numbers are displayed, but the string is not. Why is that? For some reason "ch" can't be omitted.

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

int main() {
	int i;
	float f;
	char str[80];

	ifstream in("test");
		if(!in) { cout << "Cannot open file.\n";
	return 1;
	}

	in >> i;
	in >> f;
	in.get(str,40); //Originally it was written "in>>str"

	cout << i << " " << f << " " << str << "\n"; // but then only 
	in.close(); // the first word of the string would show up
	return 0;
}
Last edited on
Hmm i'll post back in a bit, this is troubling me! I think it has something to do with the newline character.
The newline may be ending the input on the get. Does a new line get printed where the string should be?
Why use get()? Surely getline() would be better for, you know, getting lines?
std::getline(stream, buffer);
where stream is a file stream and buffer is... a buffer.

Why are you using a character array with fstream? You should use std::strings. Character arrays would be used with C fopen-fread-fclose.
Ok guys if i simply use in >> str it gives me the first word of the string. Obviously the in.get member function is being misused. Don't know yet how
Don't use the >> operator. As mcleano said, it stops at the first whitespace.

Use getline.
Yeah I know, but the getline(there's only one line anyway so that's not really bothering me at the moment) doesn't help either . I still get only 10 123.23 but no string.
As far as string class is concerned, I havent used it yet(there have been no examples in the book so far) and I'm not sure its even applicable to get(line), judging by the definition: istream& getline (char* s, streamsize n );

Nonetheless I'm new to programming so I could be completely wrong...
Aha got it! I was right it is to do with the newline characer which is why getline won't solve it at this point. Here's the solution:

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

int main() {
	int i;
	float f;
	string str;

	ifstream in("test");
		if(!in) { cout << "Cannot open file.\n";
	return 1;
	}

	in >> i;
	in >> f;
	in.ignore(); // <<<<<<<<<<<<<<<<,
	getline(in,str); //Originally it was written "in>>str"

	cout << i << " " << f << " " << str << "\n"; // but then only 
	in.close(); // the first word of the string would show up
	cin.get();
	return 0;
}


If you're not familiar with istream::ignore(), it basically extracts characters and ignores them up until it finds the delimiting character, which it also extracts and ignores (the default is '\n')
http://www.cplusplus.com/reference/iostream/istream/ignore/

Regarding your string class problem, get over it lol! I was in the same position as you where my book didn't really cover it and it was only due to this forum that I became aware of it. I can assure you your life will become much easier. Even when you need to use character arrays, you can create string objects and then convert them to C-Strings using built in functions.
Last edited on
Thank you mcleano for the effort! If I understand correctly in.ignore() extracts the '\n' character from the first file, which prevented the get(or getline) to do its job correctly because they automatically stop when '\n' is encountered. Btw I guess you meantin.getline(str, sizeof str) in line 18 and str as a char array, because if it is a string object it won't compile like that.

I'll keep in mind what you said about the string class and get familiar with it soon=).

Cheers, Fission!
Last edited on
No, I meant what I wrote. Take this program for example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>

int main()
{
   char c_str[80];
   std::string strObj;

   std::cout << "Please enter a string: ";
   std::cin.getline(c_str, 80);

   std::cout << "Please enter another string: ";
   getline(std::cin, strObj);

   std::cout << "\nC-Style string: " << c_str << "\n";
   std::cout << "String object: " << strObj;
   
   std::cin.get();
   return 0;
}


Use getline() when working with string objects, and stream_type.getline() when working with c-strings. Although even then you could just use string objects then convert to a c-string using the .c_str() function
Last edited on
Topic archived. No new replies allowed.