I don't really have the restrictions that I implied I did. The
professor said we can do it however we want, but gave no guidelines as to
how much error/format checking is involved. So of course most students
will
use proven libraries (which is smart of course, cuz it's faster and more
efficient), and assume that everything will be formatted 100% correctly,
in
order to do the least ammount of work.
Not me. I don't like using libraries when I'm first learning, and I
hate wizards in that capacity too. I like to know what's going on behind
the scenes before I start using libraries that encapsulate that
functionality. If it were up to me I'd write every program in assembly
first, to understand what was going on, then rewrite in a higher language.
So the restrictions you saw were self-imposed to force an understanding of
I/O. It works too cuz a few days ago I knew only basics about C++ I/O.
Today I'm digging through the debugger values for my ifstream variable
looking for the value that represents ios_base::iostate. I wanna find out
exactly when the input failure is occuring.
Thanks for responding though, that was a lotta helpful stuff you
wrote!!
regards,
Mario
"James Kanze" <james.kanze@[EMAIL PROTECTED]
> wrote in message
news:05af1267-ad65-4c7e-adf7-1314355902bd@[EMAIL PROTECTED]
Mar 25, 11:09 am, "drmario" <drma...@[EMAIL PROTECTED]
> wrote:
> I normally hate asking for help when I feel like I should be
> able to get something on my own. But after about 10 hours of
> trying to figure out where I'm going wrong, I have to
> surrender.
> I need to open a file and read the data in. It will be in this format:
> Gali leo 100.0
> Michael Angelo 100.00
> Mario Hollibaugh 99.4
> Christopher Polites 92.7
> Rodney Monson 100
> Michael Jordan 74.28
> Bill Gates 95
> Joanof Arc 89.6
> How Now 94
> Dane Cook 98.8
> It's supposed to be first name, last name, test score. The only thing
> guaranteed about the format is that it will be:
> (x)firstname(x)lastname(x)grade(x)
> where x=any possible number of spaces or tabs. I'm not
> allowed to use getline, and I can't use the datatype string.
In which case, I'd strongly suggest finding a different course,
because this one won't teach you anything good about C++. (If I
had to implement it in a context where std::getline and
std::string weren't available, the first thing I'd do is
implement something similar to them.)
> I have to read the first and last name as cstrings, and then
> read the grade in as double. If the person who builds the
> text file puts in an entry like:
> 95 Angelo 100.00
> well then that's their fault and the output will list 95 as
> Angelo's first name. However, if they make such an entry:
> Michael Angelo b
> he simply ends up without a grade recorded.
And what do they require if the line is just:
xxx
If I understand correctly, the requirement is that any error in
input format results in undefined behavior, and you don't have
to program for it. Which is just wrong, but in that case:
std::cin >> firstName >> lastName >> grade ;
should do the trick. (Provided you've defined an appropriate
type for firstName and lastName. You should never input like
this to a char[].)
> The general algorithm I'm using is: (I will omit EOF checks
> for simplicity's purpose)
> 1) If leading whitespace exists: (if ifstream.peek()==' ' ||
> ifstream.peek()=="\t")
> use ifstream.get to read it into a junk char var
You don't have to read into anything. Just source.get(). Or
just use:
source >> std::ws ;
However:
You really should be inputting into a type which follows the
standard input conventions. The most basic standard convention
is that the >> operator look like:
std::istream&
operator>>( std::istream& source, SomeType& dest )
{
std::istream::sentry s( source ) ;
if ( s ) {
// actual input here...
}
return source ;
}
The constructor of the sentry object will take care of skipping
white space.
Note that the system's definition of white space includes new
lines. The standard way (IMHO the only "correct" way) of
handling this is to read line by line (using getline---but you
should easily be able to write an equivalent function yourself),
then parse using the standard extraction operators on an
istringstream (or an istrstream) initialized with the line.
> 2) Once first char of first name is found
> use ifstream.get to read the chars of the first name, one by
one,
> into a string var
I though you weren't allowed to use string.
> 3) Once last char of first name is found
> insert ' ' after first name using simple assignment
> repeat all that for last name
> 4) a simlple ifstream >> to read the grade into double variable (which
> should ignore all whitespace)
Reading into an std::string variable, or a char[], also ignores
all whitespace.
Including newline. If newline is significant as a record
separator, read complete lines, then use istringstream to read
the fields in the line.
> 5) Check if ifstream is good with if(!ifstream), in other words check
if
> the user was a moron and can't follow formatting instructions. If not,
> clear the stream.
> 6) Ignore all characters (using numeric limits) until I reach the '\n'
> character.
> 7) Repeat on next line
> It's working perfectly for the first line, but for some reason
> it messes up after that. Furthermore, when I put a cout <<
> test inside my if(!ifstream), it gets printed up on the screen
> a dozen times. I can't understand why. Nothing in my sample
> file should be causing input failure.
Without seeing exactly what is happening, it's hard to say. But
in general, the restrictions you specify seem awfully
artificial. Unless the goal is to teach you how to parse a
source on which you cannot back up (in which case, either a
simple state machine or a recursive descent parser can be used).
Note, however, that all >> operators use whitespace as
delimiter, and skip leading whitespace. And that they consider
a new line as whitespace, and will skip it as well.
--
James Kanze (GABI Software) email:james.kanze@[EMAIL PROTECTED]
en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


|