fstream - write a file

C

cplusplusquestion

In following code, the statement:
fd1 << "this is test";
can't write into a file. I don't know why.

#include <iostream>
#include <fstream>
#include <stdlib.h>

using namespace std;

void read(istream& fd){
string buffer;
getline(fd,buffer);

while(!fd.eof()) {
getline(fd, buffer);
}

}

int main(int argc, char **argv) {
if (argc < 2){
cout << "arg less than 2\n";
exit(1);
}

ifstream fd(argv[1], ios::in | ios::eek:ut);
if (!fd){
cerr << "cannot open first file" << argv[1] << endl;
exit(1);
}

while (!fd.eof()){

read(fd);

fstream fd1(argv[2], ios::in | ios::eek:ut);
if (!fd1){
cerr << "cannot open second" << argv[2] << endl;
exit(1);
}

while (!fd1.eof()){
read(fd1);
fd1 << "this is test";
}

fd1.close();
}

fd.close();

return 0;
}
 
M

Michael DOUBEZ

In following code, the statement:
fd1 << "this is test";
can't write into a file. I don't know why.

#include <iostream>
#include <fstream>
#include <stdlib.h>

using namespace std;

void read(istream& fd){
string buffer;
getline(fd,buffer);

while(!fd.eof()) {

if failbit or badbit is raised before that, you will have an infinite
loop. Prefer:
while(fd)
{
getline(fd, buffer);
}

}

int main(int argc, char **argv) {
if (argc < 2){
cout << "arg less than 2\n";
exit(1);
}

ifstream fd(argv[1], ios::in | ios::eek:ut);

From your code, you may be interested in adding ios::app which set the
stream's position to the end before each output and ios::ate which does
the same on opening the file
if (!fd){
cerr << "cannot open first file" << argv[1] << endl;
exit(1);
}

while (!fd.eof()){

read(fd);

failbit may be raised outputs won't occur. try to clear it.
fd.clear();
fstream fd1(argv[2], ios::in | ios::eek:ut);

You don't write in fd1. Maybe an ifstream would be more appropriate.
Moreover, you don't need to specify ios::in|ios::eek:ut each time, this is
the default value.
if (!fd1){
cerr << "cannot open second" << argv[2] << endl;
exit(1);
}

while (!fd1.eof()){
read(fd1);
fd1 << "this is test";
}

fd1.close();
}

fd.close();

return 0;
}
 
J

James Kanze

if failbit or badbit is raised before that, you will have an
infinite loop.

And using getline, he'll probably not read the last line.
Prefer:
while(fd)
{

And of course, this can fail (but since he never used the
results, it doesn't matter).

I'll admit that I don't understand the reason behind this
function too well. You read an entire file into a local
variable, one line at a time, each line overwriting the other,
but you never do anything with the data you've read.

A simple seek to the end of file would do the same thing, more
or less. (I forget when getline does if the file doesn't end
with a '\n'.)
int main(int argc, char **argv) {
if (argc < 2){
cout << "arg less than 2\n";
exit(1);
}
ifstream fd(argv[1], ios::in | ios::eek:ut);
From your code, you may be interested in adding ios::app which
set the stream's position to the end before each output and
ios::ate which does the same on opening the file

Since he never writes to the stream, I'm not sure what the
ios::eek:ut is doing in there. I can't think of any reason, off
hand, to add ios::eek:ut to an ifstream. (Maybe to ensure that an
empty file is created, if there is no file of that name? If so,
it's pretty subtle, but no more so, I guess, than adding ios::in
to an ofstream to prevent truncating the file.)
if (!fd){
cerr << "cannot open first file" << argv[1] << endl;
exit(1);
}
while (!fd.eof()){
read(fd);
failbit may be raised outputs won't occur. try to clear it.
fd.clear();

This is more or less the same loop as is in read. I will never
be executed more than once.
fstream fd1(argv[2], ios::in | ios::eek:ut);
You don't write in fd1. Maybe an ifstream would be more
appropriate.

And again, there's no need of ios::eek:ut. Except that he does
write to fd1, after having read the entire file.
Moreover, you don't need to specify
ios::in|ios::eek:ut each time, this is the default value.
if (!fd1){
cerr << "cannot open second" << argv[2] << endl;
exit(1);
}
while (!fd1.eof()){
read(fd1);
fd1 << "this is test";

This is a tricky issue. Since he's read to end of file, eofbit
and failbit will have been set. Which means that all further
operations are no-ops, until they've been cleared.

In practice: each time you read, you should verify the status
after the read, to know if it succeeded. And each time you
change orientations, you should clear any previously detected
errors. (There's also a rule in C, which probably applies to
C++ as well, that input should not immediately follow output
without an intervening flush.)

If you've written anything, you should definitely test the
status of the stream after the close(). (If he'd have done
this, he'd have noticed that the stream was in error.
 
M

Michael DOUBEZ

James said:
And using getline, he'll probably not read the last line.


And of course, this can fail (but since he never used the
results, it doesn't matter).


I'll admit that I don't understand the reason behind this
function too well. You read an entire file into a local
variable, one line at a time, each line overwriting the other,
but you never do anything with the data you've read.

A simple seek to the end of file would do the same thing, more
or less. (I forget when getline does if the file doesn't end
with a '\n'.)

From 21.3.7.9/6
6 Effects: [...] extracts characters from is and appends them to str as
if by calling str.append(1,c) until any of the following occurs:
— end-of-file occurs on the input sequence (in which case, the getline
function calls is.setstate(ios_base::eofbit)).
— c == delim for the next available input character c (in which case, c
is extracted but not appended) (27.4.4.3)
— str.max_size() characters are stored (in which case, the function
calls is.setstate(ios_base::failbit) (27.4.4.3)
7 The conditions are tested in the order shown. In any case, after the
last character is extracted, the sentry object k is destroyed.
8 If the function extracts no characters, it calls
is.setstate(ios_base::failbit) which may throw ios_base::failure (27.4.4.3).

I would say that if the file does end with a '\n', no character are
extracted and article 8 applies (failbit is raised) which I find counter
intuitive.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

fstream Buffers 26
fstream File i/o 1
reading from either cin or file 2
A question about the fstream 0
problem with fstream 3
How to extend this code for doing "cat" 2
fstream 6
eof error using '>>' in fstream 2

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top