Hello,
I'm tring to read a text file and pull pieces of the line into separate functions.
I can open and close the file in the main. When I use the getline() it reads the whole line, I only want to read up to a certain point using strings instead of c-strings. Here is some of my code.:'(

void GetQuestion(ifstream &instream )
{   while (!instream.eof())
    {   string line;
        string sub_question;
        getline(instream,line );
        int FindFirstColon=0;
          FindFirstColon=line.find(":"); //finds first Colon
            if(FindFirstColon > -1)  
                {sub_question = line.substr(0, FindFirstColon); }
        cout<<sub_question<<":"<<endl;    

        }
}

Edited 3 Years Ago by mike_2000_17: Fixed formatting

Hello,
I'm tring to read a text file and pull pieces of the line into separate functions.
I can open and close the file in the main. When I use the getline() it reads the whole line, I only want to read up to a certain point using strings instead of c-strings.

Why? And how far?

Thanks for responding,

The why part is that it is an assingment.
Here is a line out of the text my code is reading from:
[The cout statement comes from what library?:a:abcdabdcbadcbabdcbabdabcabaabacbadba]
I need to be able to read to the first collon, pull the sentence out and cout that separately (1st function), the first letter after the collon(2nd function) and then all the letters after the second collon(3rd function)
Like I said I can pull the whole line ,but then my 2nd functions does not work in the main.

thanks for your help
John

// istream file, string str1, str2, str3
// read to the first colon
assert( geline( file, str1, ':' ) ) ;

// get first letter after the first colon
assert( geline( file, str2, ':' ) && !str2.empty() ) ;
char c = str2[0] ;

// read all the letters after the second colon
assert( geline( file, str3 ) ) ;

Sounds to me like you want to use the colon as a delimiter to split the string into tokens/separate entities for later use.

vector <string> array;
...
string token;   
istringstream iss(tmp);   
while ( getline(iss, token, ':') )   
{      
  array.push_back(token);   
}

And be careful of using the idiom eof()) for controlling file input. It doesn't work how you might expect it to...

That won't work. Be careful how you initialize the stream.

If I understand correctly, there are two delimiters you need to worry about: the end of line ('\n') and the colon (':'), where the former is primary. So...

#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
using namespace std;

...
string entire_line;
string part;

// <open file here>

// for each entire line from the file
while (getline( file, entire_line )) {

  // get yerself -another- stream to read,
  // containing only the line to tokenize.
  stringstream ss( entire_line );

  // for each token in the line (delimited by :)
  while (getline( ss, part ))
    cout << "Got me a part of the line: " << part << endl;

  // (The stringstream dies here, a new one is created for
  // the next line of the file on the next iteration of the loop)
  }

If you want to reuse your stringstream (my loop uses a different stringstream each iteration) you'll have to ss.clear(); it and ss.str( new_string ); reinitialize it (set the new string to use).

Hope this helps.

...
I have a couple of quick questions.
I'm new to the c++ programming and I do not total understand how the command: assert( getline( file, str1, ':' ) ) ; works?
Does the ':' tell the getline where to stop and what does the "assert command do? I tried using it and it gave me an error and I had to take it out. I was still able to use the info you gave me and get my functions to work in the main part of my program.

- via PM

assert is a macro (defined in the header <cassert>). what assert does is simple: assert(e): if the int expression e is evaluates to zero (false), a diagnostic message is written to stderr that includes:
a. the text of the expression e
b. the source filename (__FILE__)
c. the source line number (__LINE__)
and then calls abort.

assertions are typically used to verify that assumptions that the programmer has made while writing code hold at runtime. and if they do not, they make sure that you hear the bad news.
see http://en.wikipedia.org/wiki/Assertion_(computing) and
http://www.cprogramming.com/tips/showTip.php?tip=55&count=30&page=0

// get first letter after the first colon
assert( geline( file, str2, ':' ) && !str2.empty() ) ;

check that the call to getline succeeded and that the string str2 contains at least one char; if this is not the case, let me know immediately (fail loudly).
note: this is written with the assumption that you would not turn off assertions by defining the manifest constant NDEBUG. a better way of writing it would be

// get first letter after the first colon
bool is_ok = geline( file, str2, ':' ) && !str2.empty() ;
assert( ("attempt to read first letter after colon failed",is_ok) ) ;

though assertions have been around for a long time, it is unfortunate that many programmers do not habitually use them. geline( file, str2, ':' ); read chars one by one into str2 till a ':' is encountered; eat the ':', but do not put it into str2.
see http://www.cplusplus.com/reference/iostream/istream/getline.html

It is also a terrible use of assert().

Assert is for checking program logic errors, like this

double mySqrt ( double x ) {
  assert( x >= 0 );  // no negatives please
}

The default action of assert is to kill the program stone dead. Your user is not going to be a happy bunny if after a long sequence of input the program just dies because of some stupid typo.

Another reason for not using assert on user input is that assert does nothing in the release build. So all your careful testing in debug mode with valid input is for nothing if the user "turns evil" on the release build.

So all your user input should be guarded with if statements to check for validity, not asserts.

Comments
thanks

> It is also a terrible use of assert ....
> ... user input should be guarded with if statements to check for validity, not asserts

you are absolutely right, that was a terrible use of assert. hopefully, you put that in before johnpmii had a chance to read my earlier post. thanks, salem.

sorry, but /me takes deep breath

though assertions have been around for a long time, it is unfortunate that many programmers do not habitually use them.

I wholly disagree.

First, I don't hate assert(). Nor do I hate people using it correctly. Before going further, I'll refer back to a part of the Wikipedia article [ 1 ]. Keep in mind that assert() responds to errors by improperly terminating your program and printing an error message. This is the first half of the flaw it represents. The second half is a failure to understand the actual fallout from such a response.

1. Assert() is habitually taught and/or used as an error-handling device.
The problem with that is that its usefulness is limited to a very small domain. The kind of errors it is expected to catch are a special class: they aren't to check runtime errors, or logic errors, or hardware faults, or subsystem errors of any kind, but programmer errors. What are programmer errors?

They are a failure to design correct and robust code. Plain and simple! Harsh, huh?

Don't feel slighted. Every good programmer recognizes that this is his occupation: to discard bad design decisions and learn correct design decisions. That is part of the process of discovery vital to all software development. Heck, they've even got process models that describe this: waterfall, spiral, iterative, ... there are zillions.

Now, sometimes, particularly when working with an unfinished, poorly tested or understood, and large or complex system, robust code really is hard to design. Again, that's expected. These are the conditions where assert() may be useful. It tests a programmer's assumptions about a design --just what it is for.

However, outside of that --that is, once you have solidified and verified your design-- assert() has no place. If you are unsure that you are following your correct design when programming, I submit that either your design has not been corrected and verified or that you do not fully understand the design itself.

2. It's viral.
This isn't necessarily something that gets forced on the programmer ("programmer" said loosely here --I know how corperate development teams work... alas), rather it is often a perceptual problem. Asserts are supposed to shadow development code and disappear in production and release code. But they do more than cast shadows.

Firstly, an example: "bool is_ok" is needed to use the assert properly above --it modifies your code! and requires the programmer to specially treat it with a foo variable! It also drops responsibility for chewing up that variable on the compiler. (Most modern compilers can handle that, but it is still a fairly irresponsible thing for a tool to expect another tool to clean up its mess.) It can't work any more nicely either, because it has no way to know whether the argument is to remain in the release code or not...

Secondly, once production coding begins, discovery code is often re-used, or if not an assert may be utilized anyway as part of equivalence testing between the new and old code. So code that should have a verified, correct design (and as such, shouldn't have any assert()s) wind up with a bunch of them anyway. If that were it it wouldn't be so bad. The problem, again, is perceptual: the existence of one assert() leads to more --in production code no less-- because they are perceived as needed.

3. Examples
So, how can you distinguish appropriate and inappropriate uses of assert()? Lets have some examples.

Here's one I see flinchingly often:

void *ptr;
...
/* Somehow, somewhere, ptr is supposedly assigned value from malloc() */ 
...
assert( ptr == NULL );  /* NOT appropriate! */
free( ptr );

This fails on two counts. Firstly, ptr is neither guaranteed to be NULL nor to have value in this code. (That's a design flaw.) Secondly, once you enforce that guarantee (that is, correct the design), it is inappropriate to crash the program just to prevent free() from getting a NULL pointer. It's kind of like using a nuclear bomb to stop some guy with a gun. Sure, it stops the problem, but it kills or maims everything around it: resources are not freed and shutdown code is not executed. This is the kind of thing that causes people to use the reboot key on their computer. All because of something that could have been handled much more gracefully. In this example, the correct response is: if (ptr != NULL) free( ptr ); If it is held that the pointer must not be NULL by the time it reaches that point, you are catching some other design error, which should have been caught and handled before that point. In the worst case, it remains a possibility (even in well-designed code), so the poor sap who downloaded your program should get a nice error message or the program should be able to handle the error itself: else complain_or_handle_or_report_error_here(); Even Salem's example (which is better than anything I could come up with), is an unlikely one: at some point in time you can simply expect someone, somewhere, however unintentionally, to try to find the square root of a negative number. The best responses would be to return NAN or raise an exception and let the caller handle the error gracefully. (That's another thing: asserts() never belong in library code!) Better yet is

assert( foo >= 0 );
bar = sqrt( foo );

Now it is moved to testing your assumptions, not someone else's...

Remember, properly designed code doesn't need assert(). Properly designed code recognizes where errors may occur and either forestalls them or takes steps to recover from them, or at least it fails gracefully.

Finally, you should not be boggling the OP's mind with something that is not directly relevant to his code or making it work properly. As assert() has no place there, this also is not the place to instruct him to use it. We're supposed to be helping people, not overloading them with information about specialized needs.

/end rant
I realize my response isn't as well fleshed-out as I would like. But it touches on all the problems inherent in the use of assert(). Personally, I think new programmers should be told that if they ever need to use it they'll know, but don't bother otherwise. Again, it is a great testing and debugging tool. But most of the things it can properly test against should have proper error-handling in place. Sorry to rail on you like this. It is directed against the use of assert(), not you.

(Somehow methinks Salem did a very good job of being much more succinct than I did...)

My $0.03.

> Keep in mind that assert() responds to errors by improperly terminating your program and printing an error message
you do not understand assertions at all. assert is an effective way to catch programming errors during development and testing, and yet they are filtered out (easily) of production code. if errors are expected in production code, the technique is to throw an exception. and an unhandled exception also ends up (very properly) terminating your program.

> Assert() is habitually taught and/or used as an error-handling device.
> The problem with that is that its usefulness is limited to a very small domain.
assertions are not error handling devices. their usefulness is in veryfying that invariants are not violated in code, and if they are bringing it to the develpors attention. assert can not be used as an error handling device; it does not exist in production code.

> Somehow methinks Salem did a very good job of being much more succinct than I did...
true. also a lot more logical and coherent. and a lot less hysterical.

I did not at any time post to abuse you, yet you feel the need to abuse me?

> you do not understand assertions at all. ...
Nonsense. You cannot regurgitate my argument as proof against my argument.

> assertions are not error handling devices.
Again, that was my whole point. All the advice you gave the OP was to the contrary.


Pay attention: assert() is to be used when validating design. I love it when people start quoting me about logic and coherency.

Again, I didn't post to personally attack you (nor did I), but only to provide some information about assert() so that people reading this thread don't get lost in hijacked stuff about assert(). I wonder if the original OP is still reading this? To him I apologize for my part in wasting your bandwidth about assert(). You don't need to use it, especially for school assignments.

So believe what you like. Bye now.

This article has been dead for over six months. Start a new discussion instead.