#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::out);
if (!fd){
cerr << "cannot open first file" << argv[1] << endl;
exit(1);
}
while (!fd.eof()){
read(fd);
fstream fd1(argv[2], ios::in | ios::out);
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;
}
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::out);
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::out);
You don't write in fd1. Maybe an ifstream would be more appropriate.
Moreover, you don't need to specify ios::in|ios::out 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;
> }
--
Michael
> > #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.
And using getline, he'll probably not read the last line.
> Prefer:
> while(fd)
> {
> > getline(fd, buffer);
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::out);
> 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::out is doing in there. I can't think of any reason, off
hand, to add ios::out 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::out);
> You don't write in fd1. Maybe an ifstream would be more
> appropriate.
And again, there's no need of ios::out. Except that he does
write to fd1, after having read the entire file.
> Moreover, you don't need to specify
> ios::in|ios::out 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.)
> > }
> > fd1.close();
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.
> > }
> > fd.close();
> > return 0;
> > }
--
James Kanze (GABI Software) email:james...@gmail.com
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
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.
--
Michael