Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ifstream

73 views
Skip to first unread message

michael harrington

unread,
Feb 18, 2002, 7:25:58 AM2/18/02
to
Hello all. I have a comma delimited data file....
1,2,3,4,5,6,7
8,9,10,11,12,13,14

And the following code gets it character by character perfectly.
But is there a simple way to strip the commas and put the data
into an integer array?
TIA Mick.

# include <fstream.h>

int main()
{

ifstream fin("c:/sys7.dat"); // nb 2 SLASHES or forward slash
char ch;
while(fin.get(ch))
cout << ch;

fin.close();
cout << "\n finnished\n";

return 0;
}


Chris ( Val )

unread,
Feb 18, 2002, 10:01:42 AM2/18/02
to

"michael harrington" <mik...@bigpond.com> wrote in message
news:5m6c8.7142$wG3....@newsfeeds.bigpond.com...

Hi Michael, for what your trying to do, an container
such as the vector, would be ideal.
Here's a sample:

-- TEST DATA --
1,2,3,4,5,6,7,
8,9,10,11,12,13,14
==============

# include <iostream>
# include <fstream>
# include <string>
# include <vector>
# include <cstdlib>
using namespace std; // Generic Declaration...

int main()
{
ifstream fin("numbers.txt");
string ch;
vector<long> V;

while( getline(fin, ch, ',') )
V.push_back( strtol(ch.c_str(), 0, 10) );

vector<long>::iterator It = V.begin();
for( It; It != V.end(); ++It )
cout << *It << " ";

cout << "\nfinnished\n";

return 0;
}

Hope this help's.
Chris Val


Jim Fischer

unread,
Feb 18, 2002, 4:13:09 PM2/18/02
to

"michael harrington" <mik...@bigpond.com> wrote in message
news:5m6c8.7142$wG3....@newsfeeds.bigpond.com...

<example>

// The value 'SIZE' is the number of data items
// that are to be read in from the data file

int data[SIZE];

for ( int i = 0; i < SIZE; ++i ) {
// read the next data value from the file
// into the 'data[]' array
//
if ( in >> data[i], !in.good() )
break ;

// "eat" (read and discard) the ',' delimiter
in.get();
}

</example>

Jim


Greg Safford

unread,
Feb 18, 2002, 6:01:25 PM2/18/02
to
I'm just fooling with this stuff, but in my quick test, your routine skipped
the number following the newline, that is the '8'.

The following modified routine picks up the '8', but I'd be very happy to
hear of a more compact method:

//test.cpp

# include <iostream>
# include <fstream>
# include <string>
# include <vector>
# include <cstdlib>

# include <sstream>


using namespace std; // Generic Declaration...

int main()
{
ifstream fin("ints.txt");
string ch, ch2;
vector<long> V;
istringstream iss(ch);

while(getline(fin, ch)){
iss.clear();
iss.rdbuf()->str(ch);
while( getline(iss, ch2, ',') ){
V.push_back( strtol(ch2.c_str(), 0, 10) );
}
}

vector<long>::iterator It = V.begin();
for( It; It != V.end(); ++It )
cout << *It << " ";

cout << "\nfinished\n";

return 0;
}

"Chris ( Val )" <chri...@bigpond.com.au> wrote in message
news:1C8c8.7203$wG3....@newsfeeds.bigpond.com...

Jerry Coffin

unread,
Feb 19, 2002, 3:44:07 AM2/19/02
to
In article <5m6c8.7142$wG3....@newsfeeds.bigpond.com>,
mik...@bigpond.com says...

> Hello all. I have a comma delimited data file....
> 1,2,3,4,5,6,7
> 8,9,10,11,12,13,14
>
> And the following code gets it character by character perfectly.
> But is there a simple way to strip the commas and put the data
> into an integer array?

Yet another possibility:

#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <limits>

class my_int {
int value;
public:
virtual std::istream &get(std::istream &s) {
s >> value;
s.ignore(std::numeric_limits<int>::max(), ',');
return s;
}
operator int() { return value; }
};

int main() {
std::vector<int> vec;
my_int temp;

while (temp.get(std::cin))
vec.push_back(temp);

std::ostream_iterator<int> output(std::cout, "\n");
std::copy(vec.begin(), vec.end(), output);
return 0;
}

The emphasis here is primarily on the general approach -- just for
example, the numeric input uses opeator>>, which isn't particular
robust in the face of errors.

Another possibility would be to write a ctype facet that treats the
comma as white space, and imbue your input stream with a locale using
that facet. Once you do that, you can just read ints from the
stream, and commas get skipped over automatically.

--
Later,
Jerry.

The Universe is a figment of its own imagination.

Jerry Coffin

unread,
Feb 19, 2002, 4:13:56 AM2/19/02
to
In article <MPG.16dbbbbab...@news.direcpc.com>,
jco...@taeus.com says...

[ ... ]

> Another possibility would be to write a ctype facet that treats the
> comma as white space, and imbue your input stream with a locale using
> that facet. Once you do that, you can just read ints from the
> stream, and commas get skipped over automatically.

...but I forgot to include the code.

#include <iostream>
#include <locale>
#include <algorithm>
#include <limits>
#include <vector>

class my_ctype : public std::ctype<char> {
// VC++ 7 doesn't make table_size a const, so we use UCHAR_MAX+1
// instead -- this is kind of a hack, but works well enough for now.
mask my_table[UCHAR_MAX+1];
public:
my_ctype(size_t refs = 0)
: std::ctype<char>(my_table, false, refs)
{
// copy the original character classifaction table.
std::copy(classic_table(),
classic_table() + table_size,
my_table);
// and change ',' to be classed as white space.
my_table[','] = (mask)space;
}
};

int main() {
// create a locale using our facet, and tell cin to use it.
std::locale x(std::locale::classic(), new my_ctype);
std::cin.imbue(x);

int temp;
std::vector<int> vec;

// Now we can read ints (or longs, etc.) separated by commas,
// and the stream skips over them automagically, just like they
// were spaces (or tabs, etc.)
while (std::cin>>temp)
vec.push_back(temp);

// Copy the data to cout so we can see it, one int per line.
std::ostream_iterator<int> out(std::cout, "\n");
std::copy(vec.begin(), vec.end(), out);

// and we're done.
return 0;

Chris ( Val )

unread,
Feb 19, 2002, 10:17:33 AM2/19/02
to

"Greg Safford" <gsaf...@nyc.rr.com> wrote in message
news:9Jfc8.15375$Ci6.2...@typhoon.nyc.rr.com...

| I'm just fooling with this stuff, but in my quick test, your routine skipped
| the number following the newline, that is the '8'.
|
| The following modified routine picks up the '8', but I'd be very happy to
| hear of a more compact method:

[snip]

| > Hi Michael, for what your trying to do, an container
| > such as the vector, would be ideal.
| > Here's a sample:
| >
| > -- TEST DATA --
| > 1,2,3,4,5,6,7,
| > 8,9,10,11,12,13,14
| > ==============

[snip]

Hi Greg, it worked fine for me, but looking back at it, and
if you look at the test data I used above, I had a comma ','
following the (7) in which the OP did not. Maybe I should have
copied the test data directly from the news reader instead, that
will teach me heh :o).

Thanks for pointing that out.
Chris Val


Bob R

unread,
Feb 21, 2002, 7:03:21 PM2/21/02
to

Chris ( Val ) wrote in message
<1C8c8.7203$wG3....@newsfeeds.bigpond.com>...
>

A little side question, if anybody cares to answer it;

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

In my compiler implementation 'fstream.h' includes 'iostream.h'. Is
there any reason/situation why *both* would need to be included in a
source file?

(...just curious, 'cause I see it often.)
Thanks,
Bob R
POVrookie

Mike Wahler

unread,
Feb 21, 2002, 8:28:09 PM2/21/02
to

Bob R <remove...@worldnet.att.net> wrote in message
news:dVfd8.18301$BR3.1...@bgtnsc04-news.ops.worldnet.att.net...

>
> Chris ( Val ) wrote in message
> <1C8c8.7203$wG3....@newsfeeds.bigpond.com>...
> >
>
> A little side question, if anybody cares to answer it;
>
> ># include <iostream>
> ># include <fstream>
>
> In my compiler implementation 'fstream.h' includes 'iostream.h'.

That's possible, but you should not depend upon it,
as there's no language requirement for this.

>Is
> there any reason/situation why *both* would need to be included in a
> source file?

If you want to use 'iostream' entities, #include <iostream>.
If you want to use 'file stream' entities, #include <fstream>.
If you want to use both in the same translation unit, #include
both headers.

-Mike

Jim Fischer

unread,
Feb 21, 2002, 11:56:27 PM2/21/02
to

"Mike Wahler" <mkwa...@ix.netcom.com> wrote in message
news:a545tp$12g$1...@slb1.atl.mindspring.net...

>
> Bob R <remove...@worldnet.att.net> wrote in message
> news:dVfd8.18301$BR3.1...@bgtnsc04-news.ops.worldnet.att.net...
> >
> > Chris ( Val ) wrote in message
> > <1C8c8.7203$wG3....@newsfeeds.bigpond.com>...
> > >
> >
> > A little side question, if anybody cares to answer it;
> >
> > ># include <iostream>
> > ># include <fstream>
> >
> > In my compiler implementation 'fstream.h' includes 'iostream.h'.
>
> That's possible, but you should not depend upon it,
> as there's no language requirement for this.

Maybe I'm still whacked up on Nyquil, but the fstream family of classes are
derived from the iostream family of classes. So it makes sense to me that
the fstream header #include's the iostream header...


Jim


Mike Wahler

unread,
Feb 22, 2002, 12:46:21 PM2/22/02
to

Jim Fischer <jfisc...@attbi.com> wrote in message
news:%bkd8.3095$%D5.1...@rwcrnsc52.ops.asp.att.net...

<iostreams> declares the 'standard iostream' objects. (27.3)
<ios> declares the iostreams base classes (27.4).

So if such #including is going, on, I'd expect <fstream>
to #include <ios>, not <iostream>

This might 'make sense,' but I don't think one can depend upon this.


-Mike

Jim Fischer

unread,
Feb 22, 2002, 5:12:01 PM2/22/02
to

"Mike Wahler" <mkwa...@ix.netcom.com> wrote in message
news:a55vj2$akq$1...@slb3.atl.mindspring.net...

See 27.2.4 in 14882:1998...


Jim


Mike Wahler

unread,
Feb 22, 2002, 6:32:48 PM2/22/02
to
Jim Fischer <jfisc...@attbi.com> wrote in message news:Rmzd8.823[snip]

> > > Maybe I'm still whacked up on Nyquil, but the fstream family of
classes
> > are
> > > derived from the iostream family of classes. So it makes sense to me
> that
> > > the fstream header #include's the iostream header...
> >
> > <iostreams> declares the 'standard iostream' objects. (27.3)
> > <ios> declares the iostreams base classes (27.4).
> >
> > So if such #including is going, on, I'd expect <fstream>
> > to #include <ios>, not <iostream>
> >
> > This might 'make sense,' but I don't think one can depend upon this.
>
> See 27.2.4 in 14882:1998...

No such section. Typo?

-Mike

Jim Fischer

unread,
Feb 23, 2002, 1:56:17 AM2/23/02
to

"Mike Wahler" <mkwa...@ix.netcom.com> wrote in message
news:a56jin$2m0$1...@slb7.atl.mindspring.net...

Section 27.2 Forward Declarations [lib.iostream.forward]. Here is the text
from items 4-6 in section 27.2:

<quote>

4 The template class basic_istream serves as a base class for template
classes basic_istringstream and basic_ifstream

5 The template class basic_ostream serves as a base class for template
classes basic_ostringstream and basic_ofstream

6 The template class basic_iostream serves as a base class for template
classes basic_stringstream and basic_fstream.

</quote>


Jim


Mike Wahler

unread,
Feb 23, 2002, 11:03:46 AM2/23/02
to

Jim Fischer <jfisc...@attbi.com> wrote in message
news:l2Hd8.4024$vP.1...@rwcrnsc51.ops.asp.att.net...

Right. But those classes are not declared by <iostream>,
but by <ios> (base classes), <istream>, and <ostream>.

Or are we now 'talking past each other'? :-)

-Mike

Jim Fischer

unread,
Feb 23, 2002, 9:18:31 PM2/23/02
to

"Mike Wahler" <mkwa...@ix.netcom.com> wrote in message
news:a58dqc$kob$1...@slb5.atl.mindspring.net...

The template classes basic_[i|o|io]istream are "pre-declared" in the <ios>
header file, but they are not defined in the <ios> header file. The
basic_istream and basic_iostream classes are defined in the <istream>
header, and basic_ostream is defined in the <ostream> header. So
#include'ing <ios> in the <fstream> header will not bring in the template
code for the basic_[i|o|io]stream classes. More specifically, declaring the
existance of the basic_[i|o|io]stream classes is not sufficient if one wants
to derive new classes from them. In other words, you cannot do something
like this:

class X ; // declares the existance of class X

class Y : public X {
// definition of class Y goes here ...
};

Class X must be fully defined before class X can be used as a base class for
some derived class Y. (Class X is considered "fully defined" when the
compiler reaches the closing curly brace '}' of class X's definition block.)
So the compiler must see the complete definitions of the
basic_[i|o|io]stream classes before it can derive new classes from them.
Therefore, the <fstream> header must #include the headers <istream> and
<ostream>, and this must be done before the first line of code that derives
the basic_[i|o|io]fstream family of classes.


Noting that the synopsis for the <iostream> header file is,

namespace std {
extern istream cin;
extern ostream cout;
extern ostream cerr;
extern ostream clog;

extern wistream wcin;
extern wostream wcout;
extern wostream wcerr;
extern wostream wclog;
}


the <iostream> header (apparently) must #include the two headers, <istream>
and <ostream>. So I'm guessing that the OP's <fstream> header simply
#include's the <iostream> header, which then #include's the <istream> and
<ostream> headers.


Jim


James Dennett

unread,
Mar 10, 2002, 6:19:25 PM3/10/02
to
Jim Fischer wrote:

> Noting that the synopsis for the <iostream> header file is,
>
> namespace std {
> extern istream cin;
> extern ostream cout;
> extern ostream cerr;
> extern ostream clog;
>
> extern wistream wcin;
> extern wostream wcout;
> extern wostream wcerr;
> extern wostream wclog;
> }
>
>
> the <iostream> header (apparently) must #include the two headers, <istream>
> and <ostream>.


Actually, it does not have to. All it has to do is to declare
the 8 standard stream objects -- forward declarations for their
types are technically legal. Even if they weren't, <iostream>
could include a private header which defined the necessary
typedefs without doing the rest of the work of <istream> or
<ostream>.

IIRC, there's a Defect Report about this, because it does mean
that portability of the C++ Hello World program

#include <iostream>
int main() { std::cout << "Hello world.\n"; }

is not guaranteed: there's no reason why the relevant
operator<< needs to be declared by inclusion of <iostream>.

Similar problems, with header dependencies in the standard
library not being specified, actually make most textbook
examples non-portable according to a pedantic reading of
the standard. That's clearly not what we want, and luckily
it's not the practical result with real compilers.

--
James Dennett <jden...@acm.org>
Check out the ACCU Spring Conference 2002
4 Days, 4 tracks, 4+ languages, World class speakers
For details see: http://www.accu.org/events/public/accu0204.htm

0 new messages