reading a file....

Started by
16 comments, last by BlackWind 17 years, 1 month ago
Moved to For Beginners.
Advertisement
Quote:Original post by BlackWind
Quote:Original post by Zahlman
Please don't use sscanf() or any of that other stdio.h stuff in C++. There's really no call for it any more.

1.-why? is there any perfomance issue with the stdio?


There might be, but performance is almost never relevant when you're talking about I/O The underlying work of I/O is incredibly slow compared to any normal work done by the CPU itself - clock cycle times are literally millions of times shorter than the hard disk seek time, and there really isn't anything you can do about it. (Of course, for interactive I/O it's even worse, because waiting for a person to type something is yet again much much slower :) )

That said, the iostream classes do take care of buffering I/O automatically, are type-safe, are designed to work with other standard library types, work polymorphically (so you can work with an in-memory stream object just the same way you work with a file stream object or the console; and you never have to worry about distinguishing sprintf() vs. fprintf() - it automatically does the right thing according to which object you're using and what its type is), are newer and better thought out (yet still quite mature), and most importantly, have no realistic disadvantages vs. stdio (unless you really, really like that formatting syntax; in which case, you can get it back - in a way that doesn't cost you type-safety the way the C versions do - with boost::format).

Quote:2.- How does ifstream works? doesnt it has something like the rewind(fileptr) in the FILE* "class"?


"How it works" is of course quite complicated, just as how FILE* works. Of course, FILE* isn't a real class as you seem to be aware ;) and rewind() isn't "in" the FILE struct; it's a free function that accepts a pointer to a FILE in order to get at the data in that struct (because that's how they handled these things in C in order to appear "object-oriented").

Anyway, ifstream does have 'seek' and 'tell' member functions, and you can seek to the beginning to start over. BUT, thinking that you need to do this usually means you are doing something wrong (this is a design issue, not a language issue).

In your case, what you want to do is just use a std::vector, in order to avoid the need for counting-and-allocation. This container automatically resizes itself to accept additional contents.

Let's say we have a Triangle struct made of three Vertex's, each of which is a struct of three floats. Then, we simply make a vector of Triangles, and push_back() each Triangle as we create it from the stream. To simplify the syntax, and also provide good factoring for the code, we can overload the operator>> to read in a Vertex or a Triangle (another thing that doesn't work with stdio at all :) ) - then we'll have those functions if we ever need them for something else.

struct Vertex {  float x, y, z;};istream& operator>>(istream& is, Vertex& v) {  return is >> v.x >> v.y >> v.z;}struct Triangle {  Vertex a, b, c;};istream& operator>>(istream& is, Triangle& t) {  return is >> t.a >> t.b >> t.c;}vector<Triangle> triangles;ifstream in(filename);if (!in) {  // handle error}string line;Triangle tri;while (getline(in, line)) {  if (stringstream(line) >> tri) {    triangles.push_back(tri);  }}cerr << "I read in " << triangles.size() << " triangles.";
well, thank you all guys for the recommendations, i'll see what can i do to change my code.... also, zahlman, i liked a lot the last code you posted for reading the file

but now, i have one more question....
Quote:Original post by jyk
First you'll have to do a global replace on the name 'pVertices' (which by the way is a good example of why you shouldn't use Hungarian notation or its derivatives).

why shouldnt i use hungarian notation or derivates?


Quote:Original post by BlackWind
well, thank you all guys for the recommendations, i'll see what can i do to change my code.... also, zahlman, i liked a lot the last code you posted for reading the file

but now, i have one more question....
Quote:Original post by jyk
First you'll have to do a global replace on the name 'pVertices' (which by the way is a good example of why you shouldn't use Hungarian notation or its derivatives).

why shouldnt i use hungarian notation or derivates?


Well, one reason is that it leads to the need - as jyk is pointing out - for global replaces on names: when you change the type, you need to change the name, because otherwise the name says something about the type which isn't true.

Another reason is that it tries to do the compiler's work on behalf of the compiler. If you try to use a pointer as if it weren't a pointer, or a non-pointer as if it were a pointer, the compiler will catch that and complain. (You might need to turn up your warning level to catch all the kinds of mistakes that you find yourself commonly making.)

I could go on, but basically: it's ugly, it's harder to read, it doesn't really add information that isn't already there (because it's easy to look up the type anyway, and if you're constantly looking up types to figure out what you're doing then there's something wrong with your design), it adds extra maintenance work (never good), and it adds a potential source of *dis*information (when you forget the maintenance work, and it *will* happen eventually).
ok so....
how should i name my variables?
Quote:Original post by BlackWind
ok so....
how should i name my variables?


Generally speaking, just apply common sense and you'll be fine. Try to make sure the name explains what the purpose of the variable is; and put more effort into (that usually means longer names) naming variables that are more important (the reason we use stuff like 'i' for things like loop counters is because they're not important at all; the loop isn't about incrementing 'i' a million times, but rather about doing something to each of a million elements of some container, for example).
A variable name (or any symbol in general, really) should describe as much information about the variable as possible which you cannot also find someplace else - this means no type information, specifically, since you can find the variable's type very easily in any good IDE.

To put it another way, name a variable after why it exists instead of what kind of data it is.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

thank you guys for the replies,
i'll keep that in mind when naming my vars.....

This topic is closed to new replies.

Advertisement