C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Need help with reading/writing to/from a text file

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Joenerd
Guest





PostPosted: Thu Jul 28, 2005 11:13 am    Post subject: Need help with reading/writing to/from a text file Reply with quote



I have had some difficulty reading a text from a file with Visual
Studio's Win32 Console Application. When I build the code it gives no
errors but when I run the code...nothing happens. Instead, an empty
text file is created.Even when I create a text file with words, the run
code deletes its contents and gives me back an empty text file. Below
are two variants of the code I've been puzzling with. Can someone throw
me a bone? Thanks.

Joseph




1.

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

int main()
{
string word;
char c;
ifstream infile;
ofstream outfile;
FILE *texter=fopen("texter.txt","r");

if (infile.fail())
{
cout<<"could not open file"< exit(0);
}

while (infile>>word)
{
if (word[0]>='a' && word[0]<='z')word[0] +='A'-'a';
outfile< infile.get(c);
outfile.put(c);
}
return 0;


}

2.
#include #include <fstream>
#include<string>
#include <cstdio>
using namespace std;

main ()
{
ifstream infile("Text1.txt");
ofstream outfile("Text1.txt");
string word;
char c;
while (infile>>word)
{
if (word[0]>='a'&&word[0]<='z')word[0]+='A'-'a';
outfile<< word;
infile.get(c);
outfile.put(c);
}
return 0;

}


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Thu Jul 28, 2005 3:05 pm    Post subject: Re: Need help with reading/writing to/from a text file Reply with quote



Joenerd wrote:
Quote:
I have had some difficulty reading a text from a file with
Visual Studio's Win32 Console Application. When I build the
code it gives no errors but when I run the code...nothing
happens. Instead, an empty text file is created.Even when I
create a text file with words, the run code deletes its
contents and gives me back an empty text file. Below are two
variants of the code I've been puzzling with. Can someone
throw me a bone? Thanks.

1.

#include <iostream
#include #include #include using namespace std;

int main()
{
string word;
char c;
ifstream infile;

You create an unopened infile. You will have to open it before
use.

Quote:
ofstream outfile;

Same thing for the outfile.

Quote:
FILE *texter=fopen("texter.txt","r");

I don't know what this line is supposed to be doing. You don't
seem to use texter later in the program.

Quote:
if (infile.fail())

Intuitively, I would have expected this to always be true, but
the standard seems to say always false. It doesn't really
matter: the purpose of fail() is to report whether a preceding
operation has failed. Here, there've been no preceding
operations, so it makes no sense to call the function.

Quote:
{
cout<<"could not open file"< exit(0);
}

while (infile>>word)

Here, on the other hand, there is no doubt. Since infile has
never been opened, the >> operator must fail. Which means that
the complete expression evaluates false, and you never enter the
loop.

Quote:
{
if (word[0]>='a' && word[0]<='z')word[0] +='A'-'a';
outfile< infile.get(c);
outfile.put(c);
}
return 0;
}

To do anything useful, you'll have to open both infile and
outfile. You should also explicitly close outfile, and test its
status immediately after, just in case.

Quote:
2.
#include #include #include #include using namespace std;

main ()
{
ifstream infile("Text1.txt");

OK. Here you have implicitly opened the file for reading in the
constructor.

Normally, I would test immediately for an error, in order to
report something like "file not found".

Quote:
ofstream outfile("Text1.txt");

Here, you open the outfile implicitly in the constructor. With
the default flags -- this means that the file will be created if
it doesn't already exist, and truncated if it does exist.

Oops. The name is the same as that of the infile. You just
truncated your input to zero length.

Quote:
string word;
char c;
while (infile>>word)

Which means that this will fail first time through, without
reading anything (since there is nothing to read).

Quote:
{
if (word[0]>='a'&&word[0]<='z')word[0]+='A'-'a';

Just a word of warning here. I suspect that what you are trying
to do here is:
word[ 0 ] = std::toupper( word[ 0 ], std::locale() ) ;
If so, your code doesn't work on my machine here at work (which
uses ISO 8859-1 as its character code): some of the small
letters are not in the interval between 'a' and 'z'. It will
also fail on a machine using EBCDIC, where some of the
characters in the interval between 'a' and 'z' are not lower
case letters, and in a number of other code sets, where there is
not a constant difference between the upper case letter and the
corresponding lower case.

Of course, it also fails on my machine at home (a Linux machine
using UTF-8 as the native codeset). But then, so does the
standard solution:-). FWIW: translating lower case to upper is
*not* a good exercise for a beginner -- it can be bloody
complex. And translating to title case (which is what your code
seems to be doing) is even worse.

A simple approximation, which only handles single byte encodings
(thus, no UTF-8 -- although that is the most widespread encoding
on the Internet), is within reach of a beginner, and is worth
doing. But I'd do it by means of a state machine, reading one
character at a time, and deciding what to do with it according
to the current state. And I would definitly use the standard
functions like std::isalpha() and std::toupper to do it. The
two operand versions, because the one operand versions are a bit
tricky to use as well (since they don't accept all possible
values of a char as input).

Quote:
outfile<< word;
infile.get(c);

And what happens if this fails?

Quote:
outfile.put(c);
}
return 0;

}

Finally, of course, you definitly don't want to return 0 if
there is an error in the output. Which means that you must
explicitly close the output file, and check the status of
outfile. For that matter, you probably don't want to return 0
if there was a hardware read error. So checking infile.bad() is
probably a good idea too.

Having got this far, you doubtlessly will want to test your
code. It should be interesting to look at the output for
sequences like "abc,xyz" or "abc xyz". (Which may help you
understand why I would use a state machine.)

--
James Kanze GABI Software
Conseils 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


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Ulrich Eckhardt
Guest





PostPosted: Thu Jul 28, 2005 3:07 pm    Post subject: Re: Need help with reading/writing to/from a text file Reply with quote



Joenerd wrote:
Quote:
#include <iostream
#include #include #include using namespace std;

int main()
{
string word;
char c;
ifstream infile;
ofstream outfile;

Two C++ IOStreams, default-initialised...

Quote:
FILE *texter=fopen("texter.txt","r");

...opening a C stdio stream that has no relation whatsoever with the other
streams..

Quote:
if (infile.fail())
{
cout<<"could not open file"< exit(0);
}

...checking if a default-initialised stream has its failbit (signalling a
failed IO operation) set - which it hasn't, because no operation was ever
performed on it.

My advise: drop the #include Create small test programs, each of them only checking one feature - input,
output, and then the same using files. Once you have each of them working,
combine them. Divide and conquer.

Uli


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Simon Bone
Guest





PostPosted: Thu Jul 28, 2005 3:14 pm    Post subject: Re: Need help with reading/writing to/from a text file Reply with quote

On Thu, 28 Jul 2005 07:13:22 -0400, Joenerd wrote:

Quote:
I have had some difficulty reading a text from a file with Visual
Studio's Win32 Console Application. When I build the code it gives no
errors but when I run the code...nothing happens. Instead, an empty
text file is created.Even when I create a text file with words, the run
code deletes its contents and gives me back an empty text file. Below
are two variants of the code I've been puzzling with. Can someone throw
me a bone? Thanks.

Joseph




1.

#include <iostream
#include #include #include using namespace std;

int main()
{
string word;
char c;
ifstream infile;
ofstream outfile;


At this point you have two default constructed stream objects, infile and
outfile. They are not connected to any files, and won't be until you call
open() on them to make the connection.

Quote:
FILE *texter=fopen("texter.txt","r");

This defines a "FILE*" object, which is a different (older and less easy
to use) type. The "texter" object is completely unconnected to the
previous two stream objects. You seem to be confused by this.


Quote:

if (infile.fail())

This is a test on the as yet un-opened infile object. What do you expect
to happen...

Quote:

{
cout<<"could not open file"< exit(0);
}
}
while (infile>>word)

Now you are trying to read from the infile stream, which still is not
connected to any actual file!

Quote:
{
if (word[0]>='a' && word[0]<='z')word[0] +='A'-'a'; outfile< infile.get(c);
outfile.put(c);
}
return 0;




2.
#include #include #include #include using namespace std;

main ()
{
ifstream infile("Text1.txt");
ofstream outfile("Text1.txt");

Aha, this time you have opened the files, by using the non-default
constructor. Good.

But - if you want to both read *and* write from the same file use a single
fstream object instead.

fstream myfile("Text1.txt");

otherwise it'll confuse the lower layers of code. You also need to be
aware of the current position in the file, and current error state of the
stream object, since no-one is tracking all that for you.

That confusion is likely the root of your troubles. Keep learning!

HTH,

Simon Bone

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Dietmar Kuehl
Guest





PostPosted: Thu Jul 28, 2005 5:26 pm    Post subject: Re: Need help with reading/writing to/from a text file Reply with quote

Joenerd wrote:
Quote:
int main()
{
string word;
char c;
ifstream infile;
ofstream outfile;
FILE *texter=fopen("texter.txt","r");

if (infile.fail())
{
cout<<"could not open file"< exit(0);
}

while (infile>>word)
{

Since you never opened 'infile', this can't work. You opened a file
but this is not related at all to 'infile' beyond being opened in
the same program. The test for 'infile.fail()' was successful because
no operation was yet attempted on 'infile' which could have failed.
You might want to replace this test with e.g.

if (!infile.is_open())

Quote:
if (word[0]>='a' && word[0]<='z')word[0] +='A'-'a';

This probably should read something like

word[0] = static_cast std::toupper(static_cast<unsigned char>(word[0])));

Quote:
ifstream infile("Text1.txt");
ofstream outfile("Text1.txt");

This won't work either although here you are in fact opening both
files: opening 'outfile' will truncate the file "Text1.txt" and
thus you will probably fail to read anything from 'infile'. At best,
'infile' could have buffered part of the current context during
opening the file and you could receive this portion (the standard
makes no statement, as far as I remember, whether a file stream
buffers characters during opening).
--
<mailto:dietmar_kuehl (AT) yahoo (DOT) com> <http://www.dietmar-kuehl.de/>
<http://www.eai-systems.com> - Efficient Artificial Intelligence

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Fri Jul 29, 2005 12:30 pm    Post subject: Re: Need help with reading/writing to/from a text file Reply with quote

Simon Bone wrote:

[...]
Quote:
But - if you want to both read *and* write from the same file
use a single fstream object instead.

fstream myfile("Text1.txt");

otherwise it'll confuse the lower layers of code.

That depends enormously on what you are doing. A single fstream
object has a single position pointer. Using it for both reading
and writing generally means a lot of seeking. And in a file
opened in text mode, you can only seek to the results of a
previous tell. The use he later makes of the two file will
definitly not work if a single fstream is used.

In practice, I can see three more or less frequent cases where
you want to read and write to the same file:

-- Using the file with random access, more or less as some sort
of database. This is usually best done with a single
fstream object, like you suggest, but generally requires
opening the file in binary mode *and* maintaining fixed
length records in it. (For various reasons, I usually use
lower level system calls for this, but it can be done using
the fstream interface.)

-- Generating information, then reading it later. In this
case, you need both an ofstream and an ifstream. The
ofstream object should be opened first, since it will, if
necessary, create the file, without which, the ifstream open
will fail.

-- Modifying a file "in place". I suspect that this is
actually what the original poster wants to do. In his
particular case, it can be made to work, but it takes some
work; in the general case, it simply doesn't work. The
classical solution is to write to a temporary file, then
delete the original file, and rename the temporary file. (A
perhaps simpler solution would be to start by renaming the
orginal file, say by appending ".bak" to the name, then
creating and writing to the new file, and finally deleting
the file with the ".bak" name. But only after having
verified that you have no read or write errors -- see my
other respons.)

Quote:
You also need to be aware of the current position in the file,
and current error state of the stream object, since no-one is
tracking all that for you.

Right. Which is why you want to use two streams, to two
separate files. And not forget the standard functions remove
and rename. (This also has the advantage that you never end up
with a partially transformed file. Even if, say, the system
crashes in the middle of your program. Probably not an issue in
the original poster's case, but something any practicing
professional has to keep in mind.)

In practice, I'd almost certainly use some sort of transaction
object for the file handling, with a loop that looked something
like:

std::ctype< char > ctype
= std::use_facet< std::ctype< char > >( std::locale() ) ;
std::ctype_base const
mask = std::ctype_base::alnum ;
bool inWord = false ;
char ch ;
while( file.source().get( ch ) ) {
if ( inWord ) {
if ( ! ctype->is( mask, ch ) ) {
inWord = false ;
}
} else {
if ( ctype->is( mask, ch ) ) {
ch = ctype->toupper( ch ) ;
inWord = true ;
}
}
file.dest().put( ch ) ;
}
file.commit() ;

The file object would be responsible for creating the temporary
file, initializing the two fstreams, renaming the files and
removing the temporary. Or restoring the original situation if
its destructor is called before commit() has been called. (It's
actually in commit() where it would switch the files around.
After checking that both writing and reading had succeeded, of
course, and raising an exception if not.)

I'd also seriously consider using std::transform and stream
iterators, although this is more difficult than it would appear
at first. Technically, the standard does not allow the unary
function of transform to have any side effects, which means that
it cannot have state. Practically, since the stream iterators
are only input and output iterators, you know that transform
will visit the characters in order, and if you use shared state,
you're safe from copying, but using shared state implies
boost::shared_ptr, and that's yet another complication (another
level of indirection) for the implementor.

--
James Kanze GABI Software
Conseils 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


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Fri Jul 29, 2005 12:31 pm    Post subject: Re: Need help with reading/writing to/from a text file Reply with quote

Dietmar Kuehl wrote:

Quote:
ifstream infile("Text1.txt");
ofstream outfile("Text1.txt");

This won't work either although here you are in fact opening
both files: opening 'outfile' will truncate the file
"Text1.txt" and thus you will probably fail to read anything
from 'infile'. At best, 'infile' could have buffered part of
the current context during opening the file and you could
receive this portion (the standard makes no statement, as far
as I remember, whether a file stream buffers characters during
opening).

The C++ standard refers to the C standard for most of the
semantics of iostreams. In the C standard, there is a statement
which says: "Whether the same file can be simultaneously open
multiple times is also implementation-defined." So the second
open could also systematically fail.

The goal seems to be to replace the orginal file with one in
which all of the words are capitalized. The standard solution
for this sort of job is to use a temporary file, with a bit of
file shuffling using rename and remove when you've finished.
Although his particular transformation can be done in place, I
really see no reason to not use the standard solution here as
well, even if it isn't strictly necessary.

--
James Kanze GABI Software
Conseils 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


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
pillbug
Guest





PostPosted: Wed Aug 03, 2005 10:01 am    Post subject: Re: Need help with reading/writing to/from a text file Reply with quote

seems to me you just need some simple examples on how to read
and write files. this compiled with vc6.

#include <io.h>
#include <fcntl.h>
#include <cstdio>
#include <fstream>
// theres no error checking here.

// uses primitives
void printout (const char* filename)
{
int fd = open (filename, O_RDONLY);
int nb;
char cbuf [256];

while ((nb = read (fd, cbuf, 256)) > 0)
write (1, cbuf, nb); // 1 means stdout

close (fd);
}

// uses c stream io
void createafile (const char* filename)
{
FILE* fp = fopen (filename, "w");

fprintf (fp, "%sn", "insert entire text of c++ standard here");

fclose (fp);
}

// uses c++ stream io
void copyfile (const char* infile, const char* outfile)
{
std::ifstream fin (infile);
std::ofstream fout (outfile);

fout << fin.rdbuf();

fin.close();
fout.close();
}

int main (int argc, char** argv)
{
createafile ("file.txt");
copyfile ("file.txt", "another.txt");
printout ("another.txt");
return 0;
}

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.