473,770 Members | 4,522 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How to GET multi-word input from a *file* stream as opposed to a *console* stream?

Hi,

I've a got a little (exercise) program that reads data from a file and
puts it into struct members. I run into trouble when one of the data
pieces is comprised of several words (eg "john doe", with a space in
it).

For console input, cin.getline(var , howMuchIWant) or cin.get() has done
the trick for me in the past. It doesn't seem to work for me nearly so
well with a file stream. I wouldn't have thought cpp regarded
file/console streams as significantly different, so I assume I'm doing
something wrong. What am I doing wrong?

thanks for letting me in on the joke! :)

cdj

======example data txt file========
4
john
2000
seattle
peter
4000
san francisco
paul
100
greenlake
mary
10000
seattle
======works fine without the "san" part though======

====== code ======
/*
declare struct type
open file
get # of structs required from file
dynamically make the array of structs
display them
*/

//This routine works fine when the name and location are one word long
only.
//Need to figure out how to utilize inputFile.get or inputFile.getli ne
to
//read multiword names, locations, and the like.

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

const int STRSIZE = 60;
const int FILESIZEMAX = 1000;

int testfunction(in t arg);

struct donors {
char name[STRSIZE];
double amount;
char location[STRSIZE];
};

int main()
{
char filename[STRSIZE];
ifstream inputFile;

cout << "File name: ";
cin.getline(fil ename,STRSIZE);

inputFile.open( filename);

if (!inputFile.is_ open())
{
cout << "Couldn't open " << filename << endl;
cout << "Terminatin g execution\n";
exit(EXIT_FAILU RE);
}

cout << filename << " successfully opened." << endl;

int numDonors;
inputFile >> numDonors;

cout << "Number of donors in " << filename << ": " << numDonors <<
endl << endl;

if (numDonors==0)
{
cout << "Exiting from \'no donors\' door.\n\n";
exit(EXIT_FAILU RE);//Apparently no donor data to read
}

donors * myDonors = new donors[numDonors];
//Now I've allocated structured space for my data
cout << "Donors struct array created with " << numDonors << "
elements." << endl << endl;

//cout << "Name: ";
//cin.getline(myD onors[0].name,STRSIZE);
//cout << "You entered: " << myDonors[0].name << endl; - works fine
for console

for (int i=0; i<numDonors; i++)
{
cout << "Reading record " << i+1 << "... ";

//inputFile.getli ne(myDonors[i].name,STRSIZE);
//This works for getting multiword input from cin,
//why not for my inputFile object?

inputFile >> myDonors[i].name;
inputFile >> myDonors[i].amount;
inputFile >> myDonors[i].location;
//These work fine for single word items
//Doesn't work for multiword items

cout << "done!" << endl;
}
cout << endl;

for (int i=0; i<numDonors; i++)
{
cout << "Record #" << i+1 << ":" << endl;
cout << "Name: " << myDonors[i].name << endl;
cout << "Amount: " << myDonors[i].amount << endl;
cout << "Location: " << myDonors[i].location << endl << endl;
}

//Close file when done with it.
inputFile.close ();

//Free allocated space when done with it.
delete [] myDonors;
return 0;
}

Apr 24 '06 #1
9 2429
sh************* @gmail.com wrote:
Hi,

I've a got a little (exercise) program that reads data from a file and
puts it into struct members. I run into trouble when one of the data
pieces is comprised of several words (eg "john doe", with a space in
it).

For console input, cin.getline(var , howMuchIWant) or cin.get() has done
the trick for me in the past. It doesn't seem to work for me nearly so
well with a file stream. I wouldn't have thought cpp regarded
file/console streams as significantly different, so I assume I'm doing
something wrong. What am I doing wrong?

thanks for letting me in on the joke! :)

cdj

======example data txt file========
4
john
2000
seattle
peter
4000
san francisco
paul
100
greenlake
mary
10000
seattle
======works fine without the "san" part though======

====== code ======
/*
declare struct type
open file
get # of structs required from file
dynamically make the array of structs
display them
*/

//This routine works fine when the name and location are one word long
only.
//Need to figure out how to utilize inputFile.get or inputFile.getli ne
to
//read multiword names, locations, and the like.

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

const int STRSIZE = 60;
const int FILESIZEMAX = 1000;

int testfunction(in t arg);

struct donors {
char name[STRSIZE];
double amount;
char location[STRSIZE];
};

int main()
{
char filename[STRSIZE];
ifstream inputFile;

cout << "File name: ";
cin.getline(fil ename,STRSIZE);

inputFile.open( filename);

if (!inputFile.is_ open())
{
cout << "Couldn't open " << filename << endl;
cout << "Terminatin g execution\n";
exit(EXIT_FAILU RE);
}

cout << filename << " successfully opened." << endl;

int numDonors;
inputFile >> numDonors;

cout << "Number of donors in " << filename << ": " << numDonors <<
endl << endl;

if (numDonors==0)
{
cout << "Exiting from \'no donors\' door.\n\n";
exit(EXIT_FAILU RE);//Apparently no donor data to read
}

donors * myDonors = new donors[numDonors];
//Now I've allocated structured space for my data
cout << "Donors struct array created with " << numDonors << "
elements." << endl << endl;

//cout << "Name: ";
//cin.getline(myD onors[0].name,STRSIZE);
//cout << "You entered: " << myDonors[0].name << endl; - works fine
for console

for (int i=0; i<numDonors; i++)
{
cout << "Reading record " << i+1 << "... ";

//inputFile.getli ne(myDonors[i].name,STRSIZE);
//This works for getting multiword input from cin,
//why not for my inputFile object?
What, specifically, are you seeing that doesn't work?

inputFile >> myDonors[i].name;
inputFile >> myDonors[i].amount;
inputFile >> myDonors[i].location;
//These work fine for single word items
//Doesn't work for multiword items

cout << "done!" << endl;
}
cout << endl;

for (int i=0; i<numDonors; i++)
{
cout << "Record #" << i+1 << ":" << endl;
cout << "Name: " << myDonors[i].name << endl;
cout << "Amount: " << myDonors[i].amount << endl;
cout << "Location: " << myDonors[i].location << endl << endl;
}

//Close file when done with it.
inputFile.close ();

//Free allocated space when done with it.
delete [] myDonors;
return 0;
}


You might also want to consider using std::string instead of fixed
arrays, and then using the nonmember function std::getline() to read
strings.

You also don't deal with the possibility of corrupted data in the first
line of your file (# of donors) -- what happens if you have a negative
value there?
Apr 24 '06 #2
Sorry - here's two outputs, depending on whether the data-piece is
"francisco" or "san francisco". To my limited knowledge, the space in
"san francisco" result in the "inputFile >>" assignment being "thrown
off" by one, yielding screwy results for the stream inputs thereafter.

And yah - there's not much by the way of validation/error handling. It
seems like "covering all the bases" in that respect would take a fair
bit of coding - I just want to get the basic piece functioning
correctly first.

====== good output w/"good" data ======
====== ie, no spaces in the data ======
File name: c:\cdj.txt
c:\cdj.txt successfully opened.
Number of donors in c:\cdj.txt: 4

Donors struct array created with 4 elements.

Reading record 1... done!
Reading record 2... done!
Reading record 3... done!
Reading record 4... done!

Record #1:
Name: john
Amount: 2000
Location: seattle

Record #2:
Name: peter
Amount: 4000
Location: francisco

Record #3:
Name: paul
Amount: 100
Location: greenlake

Record #4:
Name: mary
Amount: 10000
Location: seattle
========= end good output =======

======= bad output =======
======= ie, output when the data has spaces ======
File name: c:\cdj.txt
c:\cdj.txt successfully opened.
Number of donors in c:\cdj.txt: 4

Donors struct array created with 4 elements.

Reading record 1... done!
Reading record 2... done!
Reading record 3... done!
Reading record 4... done!

Record #1:
Name: john
Amount: 2000
Location: seattle

Record #2:
Name: peter
Amount: 4000
Location: san

Record #3:
Name: francisco
Amount: -6.27744e+066
Location:

Record #4:
Name:
Amount: -6.27744e+066
Location:

Press any key to continue . . .
====== end bad output =========

Apr 24 '06 #3
On 24 Apr 2006 12:35:48 -0700 sh************* @gmail.com waved a wand
and this message magically appeared:
Hi,

I've a got a little (exercise) program that reads data from a file and
puts it into struct members. I run into trouble when one of the data
pieces is comprised of several words (eg "john doe", with a space in
it).

For console input, cin.getline(var , howMuchIWant) or cin.get() has
done the trick for me in the past. It doesn't seem to work for me
nearly so well with a file stream. I wouldn't have thought cpp
regarded file/console streams as significantly different, so I assume
I'm doing something wrong. What am I doing wrong?

thanks for letting me in on the joke! :)


Look up token(), it'll help with reading words.

--
http://www.munted.org.uk

Take a nap, it saves lives.
Apr 24 '06 #4
sh************* @gmail.com wrote:
Sorry - here's two outputs, depending on whether the data-piece is
"francisco" or "san francisco". To my limited knowledge, the space in
"san francisco" result in the "inputFile >>" assignment being "thrown
off" by one, yielding screwy results for the stream inputs thereafter.

And yah - there's not much by the way of validation/error handling. It
seems like "covering all the bases" in that respect would take a fair
bit of coding - I just want to get the basic piece functioning
correctly first.

[output redacted]

At the risk of asking the obvious, are you sure you're using getline?
The code you posted uses operator>>, which is whitespace sensitive.
Apr 24 '06 #5
In message <20************ *************** *****@munted.or g.uk>, Alex
Buell <al********@mun ted.org.uk> writes
On 24 Apr 2006 12:35:48 -0700 sh************* @gmail.com waved a wand
and this message magically appeared:
Hi,

I've a got a little (exercise) program that reads data from a file and
puts it into struct members. I run into trouble when one of the data
pieces is comprised of several words (eg "john doe", with a space in
it).

For console input, cin.getline(var , howMuchIWant) or cin.get() has
done the trick for me in the past. It doesn't seem to work for me
nearly so well with a file stream. I wouldn't have thought cpp
regarded file/console streams as significantly different, so I assume
I'm doing something wrong. What am I doing wrong?

thanks for letting me in on the joke! :)


Look up token(), it'll help with reading words.


Where? I can't find it in ISO14882.
--
Richard Herring
Apr 26 '06 #6
On 24 Apr 2006 12:35:48 -0700, sh************* @gmail.com wrote:
Hi,

I've a got a little (exercise) program that reads data from a file and
puts it into struct members. I run into trouble when one of the data
pieces is comprised of several words (eg "john doe", with a space in
it).

For console input, cin.getline(var , howMuchIWant) or cin.get() has done
the trick for me in the past. It doesn't seem to work for me nearly so
well with a file stream. I wouldn't have thought cpp regarded
file/console streams as significantly different, so I assume I'm doing
something wrong. What am I doing wrong?

thanks for letting me in on the joke! :)

cdj

======exampl e data txt file========
4
john
2000
seattle
peter
4000
san francisco
paul
100
greenlake
mary
10000
seattle
======works fine without the "san" part though======

====== code ======
/*
declare struct type
open file
get # of structs required from file
dynamically make the array of structs
display them
*/

//This routine works fine when the name and location are one word long
only.
//Need to figure out how to utilize inputFile.get or inputFile.getli ne
to
//read multiword names, locations, and the like.

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

const int STRSIZE = 60;
const int FILESIZEMAX = 1000;

int testfunction(in t arg);

struct donors {
char name[STRSIZE];
double amount;
char location[STRSIZE];
};

int main()
{
char filename[STRSIZE];
ifstream inputFile;

cout << "File name: ";
cin.getline(fil ename,STRSIZE);

inputFile.open( filename);

if (!inputFile.is_ open())
{
cout << "Couldn't open " << filename << endl;
cout << "Terminatin g execution\n";
exit(EXIT_FAILU RE);
}

cout << filename << " successfully opened." << endl;

int numDonors;
inputFile >> numDonors;
This leaves the newline character. use inputFile.get() after this call
to extract and throw away the newline character.

cout << "Number of donors in " << filename << ": " << numDonors <<
endl << endl;

if (numDonors==0)
{
cout << "Exiting from \'no donors\' door.\n\n";
exit(EXIT_FAILU RE);//Apparently no donor data to read
}

donors * myDonors = new donors[numDonors];
//Now I've allocated structured space for my data
cout << "Donors struct array created with " << numDonors << "
elements." << endl << endl;

//cout << "Name: ";
//cin.getline(myD onors[0].name,STRSIZE);
//cout << "You entered: " << myDonors[0].name << endl; - works fine
for console

for (int i=0; i<numDonors; i++)
{
cout << "Reading record " << i+1 << "... ";

//inputFile.getli ne(myDonors[i].name,STRSIZE);
//This works for getting multiword input from cin,
//why not for my inputFile object?
After putting the inputFile.get() after the extraction operator the
above getline should work.
inputFile >> myDonors[i].name;
inputFile >> myDonors[i].amount; This wil also leave the newline character. use inputFile.get() after
this call to extract and throw away the newline character.
and then use the getline() function to get the location.
inputFile >> myDonors[i].location;
//These work fine for single word items
//Doesn't work for multiword items

cout << "done!" << endl;
}
cout << endl;

for (int i=0; i<numDonors; i++)
{
cout << "Record #" << i+1 << ":" << endl;
cout << "Name: " << myDonors[i].name << endl;
cout << "Amount: " << myDonors[i].amount << endl;
cout << "Location: " << myDonors[i].location << endl << endl;
}

//Close file when done with it.
inputFile.close ();

//Free allocated space when done with it.
delete [] myDonors;
return 0;
}


The extraction operator ( >> ) does not remove the newline character
from the stream so the next call to getline() will only get the
newline character. To remove the newline character use inputFile.get()
after using the extraction operator (inputFile >> ).
Apr 26 '06 #7
On Wed, 26 Apr 2006 17:56:18 +0100 Richard Herring <ju**@[127.0.0.1]>
waved a wand and this message magically appeared:
thanks for letting me in on the joke! :)


Look up token(), it'll help with reading words.


Where? I can't find it in ISO14882.


Ok well tokenising is a trick I use to parse sentences.

std::string input("hello world!");
std::stringstre am ss(input);
std::vector<str ing> tokens;
std::string buffer;

while (ss >> buffer)
tokens.push_bac k(buffer);

Now you get a nice little vector<std::str ing> full of words. In this
case; tokens.at(0) has "hello", and tokens.at(1) has "world!".

Capise?

--
http://www.munted.org.uk

Take a nap, it saves lives.
Apr 26 '06 #8
In message <20************ *************** *****@munted.or g.uk>, Alex
Buell <al********@mun ted.org.uk> writes
On Wed, 26 Apr 2006 17:56:18 +0100 Richard Herring <ju**@[127.0.0.1]>
waved a wand and this message magically appeared:
>> thanks for letting me in on the joke! :)
>
>Look up token(), it'll help with reading words.


Where? I can't find it in ISO14882.


Ok well tokenising is a trick I use to parse sentences.

std::string input("hello world!");
std::stringstr eam ss(input);
std::vector<st ring> tokens;
std::string buffer;

while (ss >> buffer)
tokens.push_bac k(buffer);

Now you get a nice little vector<std::str ing> full of words. In this
case; tokens.at(0) has "hello", and tokens.at(1) has "world!".

Capise?


Capisco, though I see nothing called token() above ;-).

But if the input is a big file, you may get a nice _big_ vector filling
most of your memory with strings.

That's an unnecessary overhead if the intention is to scan the strings
sequentially and then discard them. This is what istream_iterato rs are
for.

std::string input("hello world");
std::stringstre am ss(input);
for (std::istream_i terator<std::st ring, char> p(ss), e; p!=e; ++p)
{
// do stuff with *p
}

The above also uses a rather simplistic definition of "word" - if your
text has punctuation, you probably need something more complex. Time to
start looking at boost::tokenize r, or even the Spirit parser.

--
Richard Herring
Apr 27 '06 #9
On Thu, 27 Apr 2006 10:25:59 +0100 Richard Herring <ju**@[127.0.0.1]>
waved a wand and this message magically appeared:
Capisco, though I see nothing called token() above ;-).

But if the input is a big file, you may get a nice _big_ vector
filling most of your memory with strings.

That's an unnecessary overhead if the intention is to scan the
strings sequentially and then discard them. This is what
istream_iterato rs are for.

std::string input("hello world");
std::stringstre am ss(input);
for (std::istream_i terator<std::st ring, char> p(ss), e; p!=e; ++p)
{
// do stuff with *p
}


Oh yes, you're right my code is only good for small strings. Thanks for
the above, I might find it useful one day!

--
http://www.munted.org.uk

Take a nap, it saves lives.
Apr 27 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
14576
by: OutsiderJustice | last post by:
Hi All, I can not find any information if PHP support multi-thread (Posix thread) or not at all, can someone give out some information? Is it supported? If yes, where's the info? If no, is it possible to make doing multi-thread stuff? Thanks. YF
37
4896
by: ajikoe | last post by:
Hello, Is anyone has experiance in running python code to run multi thread parallel in multi processor. Is it possible ? Can python manage which cpu shoud do every thread? Sincerely Yours, Pujo
12
3879
by: * ProteanThread * | last post by:
but depends upon the clique: http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&threadm=954drf%24oca%241%40agate.berkeley.edu&rnum=2&prev=/groups%3Fq%3D%2522cross%2Bposting%2Bversus%2Bmulti%2Bposting%2522%26ie%3DUTF-8%26oe%3DUTF-8%26hl%3Den ...
6
4894
by: Joe | last post by:
I have 2 multi-list boxes, 1 displays course categories based on a table called CATEGORIES. This table has 2 fields CATEGORY_ID, CATEGORY_NAME The other multi-list box displays courses based on a table called COURSES. This table has 2 fields CATEGORY_ID, COURSE_NAME. The CATEGORY_ID is a FK in COURSES and a PK in CATEGORIES. I want to populate the course list box based on any category(s)
4
17876
by: mimmo | last post by:
Hi! I should convert the accented letters of a string in the correspondent letters not accented. But when I compile with -Wall it give me: warning: multi-character character constant Do the problem is the charset? How I can avoid this warning? But the worst thing isn't the warning, but that the program doesn't work! The program execute all other operations well, but it don't print the converted letters: for example, in the string...
5
3285
by: dkelly925 | last post by:
Is there a way to add an If Statement to the following code so if data in a field equals "x" it will launch one report and if it equals "y" it would open another report. Anyone know how to modify this? Private Sub cmdPreview_Click() On Error GoTo Err_Handler 'Purpose: Open the report filtered to the items selected in the list box. 'Author: Allen J Browne, 2004. http://allenbrowne.com Dim varItem As Variant 'Selected items
17
10709
by: =?Utf-8?B?R2Vvcmdl?= | last post by:
Hello everyone, Wide character and multi-byte character are two popular encoding schemes on Windows. And wide character is using unicode encoding scheme. But each time I feel confused when talking with another team -- codepage -- at the same time. I am more confused when I saw sometimes we need codepage parameter for wide character conversion, and sometimes we do not need for conversion. Here are two examples,
0
2328
by: Sabri.Pllana | last post by:
We apologize if you receive multiple copies of this call for papers. *********************************************************************** 2008 International Workshop on Multi-Core Computing Systems (MuCoCoS'08) Barcelona, Spain, March 4 - 7, 2008; in conjunction with CISIS'08. <http://www.par.univie.ac.at/~pllana/mucocos08> *********************************************************************** Context
1
9317
by: mknoll217 | last post by:
I am recieving this error from my code: The multi-part identifier "PAR.UniqueID" could not be bound. The multi-part identifier "Salary.UniqueID" could not be bound. The multi-part identifier "PAR.UniqueID" could not be bound. The multi-part identifier "PAR.PAR_Status" could not be bound. The multi-part identifier "Salary.New_Salary" could not be bound. The multi-part identifier "Salary.UniqueID" could not be bound. The multi-part...
14
3413
by: =?ISO-8859-1?Q?Tom=E1s_=D3_h=C9ilidhe?= | last post by:
As far as I know, the C Standard has no mention of multi-threaded programming; it has no mention of how to achieve multi-threaded programming, nor does it mention whether the language or its libraries are suitable for multi-threaded programming. For people who are fond of portable C programming, what's the best way to go about multi-threaded programming? I've been reading up on POSIX threads a little, they seem pretty ubiquitous....
0
9602
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10237
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10017
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9882
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7431
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6690
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5467
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3987
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3589
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.