File reading and writing problem (SEGMENTATION FAULT)

U

utab

Hi there,
I am trying to read from a file and at the same time change certain
fields of the same field, there are 6 fields in this file like

1 2 3 4 5 6

--------/--------/--------/--------/--------/--------/ // field_width=8

For example, I position my file pointer at the begining of the 4th
fileld lets say 25th character(3*(field_width)+1) and when I try to
write to fields 4 5 6 with

inoutFile << setw(8) << setiosflags(ios::right) << "sometext";
inoutFile << setw(8) << setiosflags(ios::right) << "sometext";
inoutFile << setw(8) << setiosflags(ios::right) << "sometext";

and then I would like to go to the newline with

inoutFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// go to the newline

but in the original file I read; the 6th field is not 8 characters
width. So By writing on that field maybe I am writing over the newline
character as well but do not know for sure. SO MAYBE I NEED TO ADD A
NEWLINE CHAR TO THE END BUT HOW??

In this form I get a SEGMENTATION FAULT error.

Any help will be very much appreciated because I can not find my error
for the last 2 days and I am going mad :-(((((( .

Thanks in advance.
 
B

BobR

utab wrote in message
Hi there,
I am trying to read from a file and at the same time change certain
fields of the same field, [snip]
For example, I position my file pointer at the begining of the 4th
fileld lets say 25th character(3*(field_width)+1) and when I try to
write to fields 4 5 6 with

inoutFile << setw(8) << setiosflags(ios::right) << "sometext";
inoutFile << setw(8) << setiosflags(ios::right) << "sometext";
inoutFile << setw(8) << setiosflags(ios::right) << "sometext";

and then I would like to go to the newline with

inoutFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// go to the newline

Did you check to see if the stream is still valid?
if( inoutFile ){ /* do something */ }
if( inoutFile.good() ){ /* all is well */ }
if( inoutFile.bad() ){ /* all is NOT well */ }
if( inoutFile.eof() ){ /* you're at end-of-file */ }
if( inoutFile.fail() ){ /* all is NOT well */ }

You are probably truncating the file as soon as you write to it. Then you try
to look for the newline while you are actually at EOF.

See this thread:
From: (e-mail address removed) <[email protected]>
Newsgroups: alt.comp.lang.learn.c-c++
Date: Sunday, March 05, 2006 5:51 PM
Subject: fstream question


// read file in, modify, write file out.
std::vector<std::string> TheFile;
std::string FileName( "MyFile.txt" );
std::ifstream in( FileName.c_str() );
if(!in){ /* handle error here */ } //if(!in)
for( std::string line; std::getline(in, line); ){
TheFile.push_back(line);
}
in.close();

// modify the strings in 'TheFile'.

std::eek:fstream out( FileName.c_str() );
if(!out){ /* handle error here */ } //if(!out)
for(std::vector<std::string>::const_iterator w = TheFile.begin();
w != TheFile.end(); ++w){
out << *w << std::endl;
} // for(w)
out.close() // or, let it go out of scope


Is that any help?
 
U

utab

Hi,
I would like to read and write at the same time, it will read some
fields change them and close. Not opening and then closing them. Maybe
I may use the logic you have provided.

I appreciate the detailed explanations.

Regards.
 
D

Dietmar Kuehl

utab said:
I am trying to read from a file and at the same time change certain
fields of the same field,

I avoid doing this as it generally does not work out and is normally
slower than writing a new file anyway. There are, of course,
exceptions, e.g. when you only need to change a few places or when
you only have space for one file but not for two. In general, I would
always refrain from changing a text formatted file because this
normally includes variable field width which cannot be extended when
needed.

That said, if you really insist to change the file while being read,
you should at the very minimum obey the rules and inject a "seek"
when changing between reading and writing: the allowed stream states
can be described by some state machine and there is no direct change
between reading and writing. Instead, you need to go through a state
which can be entered by "seeking", e.g. seeking zero characters
relative to the current position.
 
U

utab

Dear Mr. Kuehl,

Yes I now can understand my error more or less. When I write to a file
position all of the positions after that point is changing and then I
have to look everytime where I am writing.

But is not this the same for separate files as well when you try to
open a file in write mode, again you are changing the positions or am I
completely confusing things.

For example I tried a ver simple example;

int main(){
14 int lines=0;
15 char ch;
16 fstream inFile("out1.bdf",ios::in | ios::eek:ut);
17 if (!inFile ){ // Always test file open
18 cerr << "Error opening input file" << endl;
19 exit(1);
20 }
21 while(inFile.get(ch)){
22 cout << ch << endl;
23 inFile << "deneme";
24 if(inFile.rdstate()==ios::goodbit)
25 cout << "No ERRORS!!!" << endl;
26 if (ch != '\n')
27 inFile.ignore(100, '\n'); // go to the newline
28 }
29 inFile.close();

I can just print a $ character from the file however I wanted to write
sometext "deneme" in this case after reading that character. But I can
only read the first line(first $) and could not write in the file.

The head of the file is something like below;

$ NASTRAN input file created by the MSC MSC.Nastran input file
$ translator ( MSC.Patran 13.0.053 ) on March 09, 2006 at 10:23:05.
$ Direct Text Input for Nastran System Cell Section
$ Direct Text Input for File Management Section
$ Normal Modes Analysis, Database
SOL 103
....

I surely have a problem in understanding my problem.

Thanks.
 
D

Dietmar Kuehl

utab said:
When I write to a file
position all of the positions after that point is changing

Nope. You just overwrite the characters at the position you are.
This my cause field separators to become useless because the
simply get overwritten.

A file is a pretty static data structure. You can change the
characters within but moving them effectively means that you need
to rewrite the whole file. You can only reasonably extend the file
at its end. Although there are systems which support more flexible
file handling, only this very static view is supported by C++.

But is not this the same for separate files as well when you try to
open a file in write mode, again you are changing the positions or am I
completely confusing things.

What I'm proposing is that you open two files:
- one for input only
- one for output only

Unless you have very strong reasons to do differently and you know what
you are doing, you should not open a file for both reading and writing.
If necessary, you might remove the original and replace it with the
new file at the very end of the processing or even copy the newly
created file to the original.

That is, I would use code similar to this for what you apparently
want to do:

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

int main()
{
std::ifstream in("out1.bdf");
std::eek:fstream out("out1.bdf.tmp");
if (!in || !out)
return (std::cerr << "error opening file"), EXIT_FAILURE;

for (std::string line; std::getline(in, line); )
if (line[0] == '$')
out << "deneme\n";
else
out << line << "\n";

in.close();
out.close();

remove("out1.bdf");
rename("out1.bdf.tmp", "out1.dbf");
}

This approach also makes it easier to test the program because you
don't keep changing your source file: you would just comment the
last two lines and work on the program until the temporary file
meets your expectations. Only then you put the last two lines in.
 
U

utab

Yes Thanks but still no replies.

Could you please have a look at my first thread I would like to change
some fields in a line?

1 2 3 4 5 6

--------/--------/--------/--------/--------/--------/ // field_width=8


lets say I would like to change field 3 on all the relevant lines of a
file. So then I would have to write on the 3rd field and then go to the
newline and again write on the 3rd field and go to the newline and so
on...

I deeply appreciate your replies, many thanks.
 
D

Dietmar Kuehl

utab said:
Yes Thanks but still no replies.

Well, I think it is your part to work out the details specific to
your needs. ...and I think I provided you with sufficient
information on how to actually do it.
Could you please have a look at my first thread I would like to change
some fields in a line?

Yes. ... and what is your specific problem? Just do it!
1 2 3 4 5 6

--------/--------/--------/--------/--------/--------/ // field_width=8


lets say I would like to change field 3 on all the relevant lines of a
file.


OK. I replace field three with a static text here but it could be
anything you want to put there:

std::ifstream in("in.file");
std::eek:fstream out("out.file");
std::string replacement("01234567");
for (std::string line; std::getline(in, line); )
{
std::copy(replacement.begin(), replacement.end(),
line.begin() + 18);
out << line << "\n";
}

Obviously, if the fields are not fixed width you might need to
locate the appropriate field separators, e.g. using string's
'find()' method and/or 'std::find()'. Also, you might need to use
string manipulation operations which could insert characters when
necessary. The above code just replaces existing characters and
assumes a fixed field width (eight character plus one separator).
 

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

Staff online

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top