Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > help me understand this cin/fstream behavior

Reply
Thread Tools

help me understand this cin/fstream behavior

 
 
Danny Anderson
Guest
Posts: n/a
 
      01-24-2004
Hola-
I didn't get any responses on a previous post, so I am trying to reword my
problem and post compile-able code that exhibits the behavior I am
describing.

On the second iteration of the loop below, the file opened is the default
(which in this case is ".csv", which makes a 'hidden' file for Linux
folk). The step that prompts for a file name step is skipped completely.
Why? Is this a cin issue or does it have something to do with the
filestream?

As always, comments and suggestions appreciated, Danny

//---start code
#include <iostream>
#include <string>
#include <vector>
#include <fstream>


using namespace std;


//---function prototypes

void pause(string s);
bool user_is_not_finished();
string get_filename(string filetype);



int main()
{

string foo;
ofstream dataOut;


do
{
//---open report file for writing
dataOut.open(get_filename("report").c_str()); if(!dataOut)
{cout << "ERROR: couldn't open output file..."; return 1;}
else
{cout << "ready to start...\n" << endl;}

//---get information for report
cout << "Enter some text: ";
getline(cin, foo);
dataOut << foo << endl;
dataOut.close();

}while(user_is_not_finished() );

pause("end of program...");
return 0;
}
}
//---function definitions


void pause(string s)
{
char c;
cout << endl << s << "...enter a key to continue: "; cin >> c;
}
}

bool user_is_not_finished()
{
char user_choice;
bool is_not_finished;

cout << endl <<"[Q]uit program or enter another [r]eport? "; cin >>
user_choice;

while(user_choice!='Q'&& user_choice!='q'&& user_choice!='r'&&
user_choice!='R')
{
//---keep prompting until a valid answer is encountered cout <<
"[Q]uit program or enter another [r]eport? "; cin >> user_choice;
}
if(user_choice=='r'|| user_choice=='R')
{
is_not_finished=true;
}
else
{
is_not_finished=false;
}
}
return is_not_finished;
}
}

/* get_filename(string filetype)
* purpose: get the name of the file to be opened *
* input: a string that is either "report" or "material list". other
strings * can be valid as long as they are defined in the function body
* output: a string that can be sent to the a fstream.open command (after
* being converted to a c_str
*/

string get_filename(string filetype)
{
string filename;
string dummy;

if(filetype=="report")
{
cout << "Output file? [bldg_report] ";

getline(cin, filename);
// if(filename.empty())
// {filename="bldg_report.csv";}
//else
{filename+=".csv";}
}
else if(filetype=="material list")
{
cout << "Material List Filename? [dfi_master_mtl.txt] ";
getline(cin, filename);
if(filename.empty())
{filename="dfi_master_mtl.txt";}


}
return filename;
}
 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      01-24-2004
On Fri, 23 Jan 2004 19:57:21 -0500, "Danny Anderson" <(E-Mail Removed)> wrote:

>Hola-
>I didn't get any responses on a previous post, so I am trying to reword my
>problem and post compile-able code that exhibits the behavior I am
>describing.
>
>On the second iteration of the loop below, the file opened is the default
>(which in this case is ".csv", which makes a 'hidden' file for Linux
>folk). The step that prompts for a file name step is skipped completely.
>Why? Is this a cin issue or does it have something to do with the
>filestream?
>
>As always, comments and suggestions appreciated, Danny
>
>//---start code
>#include <iostream>
>#include <string>
>#include <vector>
>#include <fstream>
>
>
>using namespace std;
>
>
>//---function prototypes
>
>void pause(string s);
>bool user_is_not_finished();
>string get_filename(string filetype);
>
>
>
>int main()
>{
>
> string foo;
> ofstream dataOut;
>
>
> do
> {
> //---open report file for writing
> dataOut.open(get_filename("report").c_str()); if(!dataOut)
> {cout << "ERROR: couldn't open output file..."; return 1;}
> else
> {cout << "ready to start...\n" << endl;}


Suggest formatting this more readable.

Place 'if' at the start of separate line.



>
> //---get information for report
> cout << "Enter some text: ";
> getline(cin, foo);
> dataOut << foo << endl;
> dataOut.close();
>
> }while(user_is_not_finished() );
>
> pause("end of program...");
> return 0;
>}
>}


What's that second brace? This might be the problem.



>//---function definitions
>
>
>void pause(string s)
>{
> char c;
> cout << endl << s << "...enter a key to continue: "; cin >> c;
>}
>}



What's that second brace? This might be the problem.



>bool user_is_not_finished()
>{
> char user_choice;
> bool is_not_finished;
>
> cout << endl <<"[Q]uit program or enter another [r]eport? "; cin >>
> user_choice;
>
> while(user_choice!='Q'&& user_choice!='q'&& user_choice!='r'&&
> user_choice!='R')
> {
> //---keep prompting until a valid answer is encountered cout <<
> "[Q]uit program or enter another [r]eport? "; cin >> user_choice;
> }
> if(user_choice=='r'|| user_choice=='R')
> {
> is_not_finished=true;
> }
> else
> {
> is_not_finished=false;
> }
> }


What's that second brace? This might be the problem.



> return is_not_finished;
>}
>}



What's that second brace? This might be the problem.


>
>/* get_filename(string filetype)
> * purpose: get the name of the file to be opened *
> * input: a string that is either "report" or "material list". other
> strings * can be valid as long as they are defined in the function body
> * output: a string that can be sent to the a fstream.open command (after
> * being converted to a c_str
> */
>
>string get_filename(string filetype)
>{
> string filename;
> string dummy;
>
> if(filetype=="report")
> {
> cout << "Output file? [bldg_report] ";
>
> getline(cin, filename);
> // if(filename.empty())
> // {filename="bldg_report.csv";}
> //else
> {filename+=".csv";}
> }
> else if(filetype=="material list")
> {
> cout << "Material List Filename? [dfi_master_mtl.txt] ";
> getline(cin, filename);
> if(filename.empty())
> {filename="dfi_master_mtl.txt";}
>
>
> }
> return filename;
>}


 
Reply With Quote
 
 
 
 
Mike Wahler
Guest
Posts: n/a
 
      01-24-2004

"Danny Anderson" <(E-Mail Removed)> wrote in message
news(E-Mail Removed)...
> Hola-
> I didn't get any responses on a previous post, so I am trying to reword my
> problem and post compile-able code that exhibits the behavior I am
> describing.
>
> On the second iteration of the loop below, the file opened is the default
> (which in this case is ".csv", which makes a 'hidden' file for Linux
> folk). The step that prompts for a file name step is skipped completely.
> Why? Is this a cin issue or does it have something to do with the
> filestream?
>
> As always, comments and suggestions appreciated, Danny
>
> //---start code
> #include <iostream>
> #include <string>
> #include <vector>
> #include <fstream>
>
>
> using namespace std;
>
>
> //---function prototypes
>
> void pause(string s);
> bool user_is_not_finished();
> string get_filename(string filetype);
>
>
>
> int main()
> {
>
> string foo;
> ofstream dataOut;
>
>
> do
> {
> //---open report file for writing
> dataOut.open(get_filename("report").c_str()); if(!dataOut)
> {cout << "ERROR: couldn't open output file..."; return 1;}
> else
> {cout << "ready to start...\n" << endl;}
>
> //---get information for report
> cout << "Enter some text: ";
> getline(cin, foo);
> dataOut << foo << endl;
> dataOut.close();
>
> }while(user_is_not_finished() );
>
> pause("end of program...");
> return 0;
> }
> }
> //---function definitions
>
>
> void pause(string s)
> {
> char c;
> cout << endl << s << "...enter a key to continue: "; cin >> c;
> }
> }
>
> bool user_is_not_finished()
> {
> char user_choice;
> bool is_not_finished;
>
> cout << endl <<"[Q]uit program or enter another [r]eport? "; cin >>
> user_choice;
>
> while(user_choice!='Q'&& user_choice!='q'&& user_choice!='r'&&
> user_choice!='R')
> {
> //---keep prompting until a valid answer is encountered cout <<
> "[Q]uit program or enter another [r]eport? "; cin >> user_choice;
> }
> if(user_choice=='r'|| user_choice=='R')
> {
> is_not_finished=true;
> }
> else
> {
> is_not_finished=false;
> }
> }
> return is_not_finished;
> }
> }
>
> /* get_filename(string filetype)
> * purpose: get the name of the file to be opened *
> * input: a string that is either "report" or "material list". other
> strings * can be valid as long as they are defined in the function body
> * output: a string that can be sent to the a fstream.open command (after
> * being converted to a c_str
> */
>
> string get_filename(string filetype)
> {
> string filename;
> string dummy;
>
> if(filetype=="report")
> {
> cout << "Output file? [bldg_report] ";
>
> getline(cin, filename);
> // if(filename.empty())
> // {filename="bldg_report.csv";}
> //else
> {filename+=".csv";}
> }
> else if(filetype=="material list")
> {
> cout << "Material List Filename? [dfi_master_mtl.txt] ";
> getline(cin, filename);
> if(filename.empty())
> {filename="dfi_master_mtl.txt";}
>
>
> }
> return filename;
> }


You have other issues to address first:

f:\danny.cpp(45) : error C2143: syntax error : missing ';' before '}'
f:\danny.cpp(45) : error C2143: syntax error : missing ';' before '}'
f:\danny.cpp(45) : error C2143: syntax error : missing ';' before '}'
f:\danny.cpp(50) : error C2143: syntax error : missing ';' before '{'
f:\danny.cpp(50) : error C2447: missing function header (old-style formal
list?)
f:\danny.cpp(54) : error C2143: syntax error : missing ';' before '}'
f:\danny.cpp(54) : error C2143: syntax error : missing ';' before '}'
f:\danny.cpp(54) : error C2143: syntax error : missing ';' before '}'
f:\danny.cpp(57) : error C2143: syntax error : missing ';' before '{'
f:\danny.cpp(57) : error C2447: missing function header (old-style formal
list?)
f:\danny.cpp(79) : error C2143: syntax error : missing ';' before 'return'
f:\danny.cpp(80) : error C2143: syntax error : missing ';' before '}'
f:\danny.cpp(80) : error C2143: syntax error : missing ';' before '}'
f:\danny.cpp(80) : error C2143: syntax error : missing ';' before '}'
f:\danny.cpp(81) : error C2143: syntax error : missing ';' before '}'
f:\danny.cpp(81) : error C2143: syntax error : missing ';' before '}'
f:\danny.cpp(92) : error C2143: syntax error : missing ';' before '{'
f:\danny.cpp(92) : error C2447: missing function header (old-style formal
list?)
Error executing cl.exe.

swaptest.exe - 18 error(s), 0 warning(s)


 
Reply With Quote
 
Danny Anderson
Guest
Posts: n/a
 
      01-24-2004
I must not have done a very good job on the cut and paste the first
go-round. My apologies. This is the exact example code that I compiled
on my machine- I promise!

//example for usenet
#include <iostream>
#include <string>
#include <vector>
#include <fstream>


using namespace std;


//---function prototypes

void pause(string s);
bool user_is_not_finished();
string get_filename(string filetype);



int main()
{

string foo;
ofstream dataOut;


do
{
//---open report file for writing
dataOut.open(get_filename("report").c_str());
if(!dataOut)
{cout << "ERROR: couldn't open output file..."; return 1;}
else
{cout << "ready to start...\n" << endl;}

//---get information for report
cout << "Enter some text: ";
getline(cin, foo);
dataOut << foo << endl;
dataOut.close();

}while(user_is_not_finished() );

pause("end of program...");
return 0;
}

//---function definitions


void pause(string s)
{
char c;
cout << endl << s << "...enter a key to continue: ";
cin >> c;
}


bool user_is_not_finished()
{
char user_choice;
bool is_not_finished;

cout << endl <<"[Q]uit program or enter another [r]eport? ";
cin >> user_choice;

while(user_choice!='Q'&& user_choice!='q'&& user_choice!='r'&& user_choice!='R')
{
//---keep prompting until a valid answer is encountered
cout << "[Q]uit program or enter another [r]eport? ";
cin >> user_choice;
}
if(user_choice=='r'|| user_choice=='R')
{
is_not_finished=true;
}
else
{
is_not_finished=false;
}

return is_not_finished;
}



string get_filename(string filetype)
{
string filename;
string dummy;

if(filetype=="report")
{
cout << "Output file? [bldg_report] ";

getline(cin, filename);
// if(filename.empty())
// {filename="bldg_report.csv";}
//else
{filename+=".csv";}
}
else if(filetype=="material list")
{
cout << "Material List Filename? [dfi_master_mtl.txt] ";
getline(cin, filename);
if(filename.empty())
{filename="dfi_master_mtl.txt";}

}

return filename;
}




 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      01-24-2004
On Sat, 24 Jan 2004 08:03:39 -0500, "Danny Anderson" <(E-Mail Removed)> wrote:

>I must not have done a very good job on the cut and paste the first
>go-round. My apologies. This is the exact example code that I compiled
>on my machine- I promise!


Goodie.

OK, the program is performing exactly as you describe, and also exactly
as it should according to the Holy Standard.

It isn't performing as you expect, sort of "skipping" one input operation,
because you have the equivalent of the following:


#include <iostream>
#include <string>

int main()
{
char c;
std::string s;

std::cout << "A char, please: " << std::flush;
std::cin >> c;

std::cout << "A line, please: " << std::flush;
std::getline( std::cin, s );

std::cout << "Finished!" << std::endl;
}


When the first read operation is finished there is a 'newline' character,
the one marked the end of the first line, left in the buffer.

The second read operation interprets this as an empty line entered by the
user.

What you need to do to get the behavior you have so far expected is to
clear the read buffer, e.g. by using a skip operation or readline.

 
Reply With Quote
 
Martin Eisenberg
Guest
Posts: n/a
 
      01-26-2004
Danny Anderson wrote:

[code snipped]

Hi,

I've played around with your code a bit. Any comments are
appreciated.

#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
#include <cassert>

using namespace std;


//---function prototypes

// void pause(string s);
/* I chose a more descriptive name. Also, the
message is not related to the pausing as such.
*/

void wait_for_user();

// bool user_is_not_finished();
/* Function names containing "not" eventually
lead to confusing double negations. Turn the
condition around or formulate it positively.
Besides, returning the two-valued bool doesn't
accomodate extension.
*/

typedef enum { dReport, dMaterialList, dQuit } UserDesire;

UserDesire get_user_desire();

// string get_filename(string filetype);
/* Identifying the file types by strings
is imho not appropriate in this program.
It might be in some situations where the
wanted type is specified by an entity
outside your code, or where the available
file types are runtime-configurable.
*/

string get_output_filename(UserDesire desire);


//---

int main()
{
string out_text;
ofstream out_file;
UserDesire desire = get_user_desire();

while(desire != dQuit) {
out_file.open(get_output_filename(desire).c_str(), ios::app);
if(!out_file) {

// Note the "cerr".

cerr << "ERROR: couldn't open output file...\n";
return 1;
}

cout << "Enter some text: ";
getline(cin, out_text);
out_file << out_text << endl;

out_file.close();
desire = get_user_desire();
}

cout << "end of program...";
wait_for_user();
return 0;
}


//---function definitions

void wait_for_user()
{
string foo;
cout << "\n ...hit <Enter> to continue.";
getline(cin, foo);
}


UserDesire get_user_desire()
{
string user_choice;

// The loop terminates upon valid input.

while(true) {
cout << "Add to [r]eport, add to [m]aterial list, [q]uit? ";
getline(cin, user_choice);
if(!user_choice.empty()) {
switch(tolower(user_choice[0])) {
case 'r' : return dReport;
case 'm' : return dMaterialList;
case 'q' : return dQuit;
}
}
}
}


string get_output_filename(UserDesire desire)
{
assert(desire != dQuit);

static const string DEFAULT_REPORT_FILE
(
// "bldg_report"
""
);
static const string DEFAULT_MATERIAL_FILE("dfi_master_mtl.txt");

string filename;

switch(desire) {
case dReport :
cout << "Report file? [" << DEFAULT_REPORT_FILE << "] ";
getline(cin, filename);
if(filename.empty())
{ filename = DEFAULT_REPORT_FILE; }

filename += ".csv";
break;

case dMaterialList :
cout << "Material List Filename? ["
<< DEFAULT_MATERIAL_FILE << "] ";
getline(cin, filename);
if(filename.empty())
{ filename = DEFAULT_MATERIAL_FILE; }
break;

default :

// If we get here, this function is incomplete.

assert(false);
}

return filename;
}


//---end of file
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Matrix: Need help to understand this behavior Marcio Braga Ruby 9 08-18-2008 10:38 PM
unable to understand constructor behavior neo C++ 4 12-30-2006 12:00 AM
QuickSort . I don't understand this behavior camotito C Programming 2 04-24-2006 08:45 PM
Read all of this to understand how it works. then check around on otherRead all of this to understand how it works. then check around on other thelisa martin Computer Support 2 08-18-2005 06:40 AM
i do not understand this behavior: url tacked onto "localhost" Timo ASP .Net 1 03-03-2005 07:55 PM



Advertisments