• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 595
  • Last Modified:

how does ifstream works?

qn: I've got a function that uses ifstream to read inputs from a text file.
void loadFile(char*landfile){
ifstream fin(landfile);
fin >> jtn_file >> rd_file >> signal_file;
     fin.close();  
     ITPSInit(jtn_file, rd_file,signal_file );
}
how does 'fin' store the information of jtn_file etc?
jtn_file:
[No of jtn]
72
[ID,name,numRoad]
1 junction1 2  
0
hav999
Asked:
hav999
1 Solution
 
SalteCommented:
Here is how ifstream works:

if you do:

ifstream file(....blah blah blah...);

T obj;

file >> obj;

Then you call a function or operator overload:

istream & operator >> (istream & is, T & obj);

Exactly which operator overload this is depends on the type T. For example if T is a char buf[] the T is actually a char * and the reference isn't needed (and not used) so the overload is:

istream & operator >> (istream & is, char * obj);

Now, this function does not have any clue about the size of obj and it simply assumes that obj is pointing to some location that is "big enough". This means that if you read 40 characters then the obj must point to some buffer that has room for at least 41 characters - the 40 characters read and the terminating NUL character.

If the buffer is smaller than this the program will most likely crash or weird things will start to happen.

If the buffer is bigger than 41 that's ok, that just means that there will be unused space after the terminating NUL character.

Another example is if T is an integer:

int intvar;

file >> intvar;

This overload will read the next few characters from the file and if they are digits they will be read and converted to a number. There might be a sign (+ or -) in front of the number, that is OK and is handled by the overload. When the reading encounter a character that isn't part of the number it stops reading (do not read that character) and store the value into the variable intvar.

Similarly for the case:

unsigned int uintvar;
file >> uintvar;

Except in this case it won't understand a - in front of the value and will most likely (I haven't checked this) not like a + either. The value is read and stored into uintvar.

A better way to read a string is:

string str;
file >> str;

This will read a string just like in the first case with the char buf[41] case but the string will be dynamically sized to always be big enough - you don't have to worry about the size of str in this case.

You probably notice that these overloads return istream & as return type, this is so that:

file >> a >> b >> c;

can be done properly, the above is the same as:

((file >> a) >> b) >> c;

so first file >> a will be called then the return value being a reference to the istream will be used to compute

return >> b

where 'return' is the return value from the (file >> a) call. When this function returns the (return >> c) will be called with return being the return value from (return >> b).

In other words, the:

file >> a >> b >> c;

is executed exactly as if you had written:

file >> a;
file >> b;
file >> c;

except that the later two won't see the object as a ifstream type but rather istream type. This is ok since the file >> foo; functions aren't defined in ifstream class anyway, they are defined in the istream class which ifstream derives from.

Note that the intvalue reading will stop when it comes to a non-digit. The string reading overload will sto when it encounters a non-graphical character (control character or space or blank character).

If you wanted the string to stop before that or to read spaces and stop on a different character you need to use a different function than the >> overload.

file.getline() can be used, it has one form with 3 arguments giving a buffer, a number n and a stop character delim.

delim defaults to '\n' so if you don't specify it it will read one line and that's why the function is called 'getline()'.

the number n refer to the size of the buffer, specifically it will read at most n-1 chars and store them into the buffer and then add an extra NUL byte after those characters. If it reads the stop character it will stop and not consume that stop character even if it has read fewer than n-1 characters.

It is possible it actually reads up to n chars and not n-1 in that case it won't store any NUL byte at the end, which is bad sinze you then get a string that isn't NUL terminated. It is usually a good idea to make the buffer big enough so that it never reads n characters in getline() and always stop on stop character so that you are sure you always get a NUL character at the end.

Hope this explains.

Alf
0
 
bcladdCommented:
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Answered: Points to Salte

Please leave any comments here within the next seven days. Experts: Silence
means you don't care.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

-bcl (bcladd)
EE Cleanup Volunteer
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now