ofstream problem

R

Ron Eggler

Hi,

I'm trying to write to a text file with following code:
std::eek:fstream out("/usr/share/NovaxTSP/INITreport.txt", std::ios_base::in |
std::ios_base::eek:ut | std::ios_base::app);
if(!out) { // if out couldn't be opened, print error and exit
std::cout << "Cannot open reportfile:
\"/usr/share/NovaxTSP/INITreport.txt\"." << std::endl;
exit(0);
}
double num = 100.45;
char str[100];
strcpy(str, newLine.c_str());
strcat(str,"\n\r");
out.write((char *) &num, sizeof(double));
out.write(str, strlen(str));
out.close();

the folder /usr/share/NovaxTSP/ has permissions set to 775 and the
application is run as root but i still always get: Cannot open
reportfile: "/usr/share/NovaxTSP/INITreport.txt".
Why??? I don't understand, i made a df -h and there's enough space available
as well.
Does anyone have any other ideas on what to check?
I also touched the file before appending but that didn't change it either.

I appreciate every input!

Thank you to help me further!

Ron
 
G

Gianni Mariani

Ron said:
Hi,

I'm trying to write to a text file with following code:
std::eek:fstream out("/usr/share/NovaxTSP/INITreport.txt", std::ios_base::in |
std::ios_base::eek:ut | std::ios_base::app);
if(!out) { // if out couldn't be opened, print error and exit
std::cout << "Cannot open reportfile:
\"/usr/share/NovaxTSP/INITreport.txt\"." << std::endl;
exit(0);
}
double num = 100.45;
char str[100];

NEVER EVER EVER DECLARE A CHAR ARRAY ON STACK
strcpy(str, newLine.c_str());

AND THEN FILL IT WITH AN UNBOUND STRING.
strcat(str,"\n\r");

"\n\r" is operating system specific. If you write that to some
platforms (MSVC) for example, you'll get more than one \r.

What's wrong with:
std::string str = newLine + "\n";
?

That code above will work correctly for any "newLine".
out.write((char *) &num, sizeof(double));

This is also endian dependant - not good depending on your use for the
output file. Are you really trying to write the bitwise representation
of the machine specific "double" type ?
out.write(str, strlen(str));
out.close();

the folder /usr/share/NovaxTSP/ has permissions set to 775 and the
application is run as root but i still always get: Cannot open
reportfile: "/usr/share/NovaxTSP/INITreport.txt".

If you're running under linux, try

touch /usr/share/NovaxTSP/INITreport.txt

Or run your program under strace and see what error you're getting back
from the OS.
 
D

diligent.snail

Hi,

I'm trying to write to a text file with following code:
std::eek:fstream out("/usr/share/NovaxTSP/INITreport.txt", std::ios_base::in |
std::ios_base::eek:ut | std::ios_base::app);
if(!out) { // if out couldn't be opened, print error and exit
std::cout << "Cannot open reportfile:
\"/usr/share/NovaxTSP/INITreport.txt\"." << std::endl;
exit(0);
}
double num = 100.45;
char str[100];
strcpy(str, newLine.c_str());
strcat(str,"\n\r");
out.write((char *) &num, sizeof(double));
out.write(str, strlen(str));
out.close();

the folder /usr/share/NovaxTSP/ has permissions set to 775 and the
application is run as root but i still always get: Cannot open
reportfile: "/usr/share/NovaxTSP/INITreport.txt".
Why??? I don't understand, i made a df -h and there's enough space available
as well.
Does anyone have any other ideas on what to check?
I also touched the file before appending but that didn't change it either.

I appreciate every input!

Thank you to help me further!

Ron

Hello,

I tried to replicate your test environment, and it worked for me (I
had to comment out 'strcpy(str, newLine.c_str());', for newLine is not
defined).

You can try to run:
strace ./a.out
(a.out is your compiled executable).

You should get further information on the error near end of trace, for
example:
open("/usr/share/NovaxTSP/INITreport.txt", O_RDWR|O_CREAT|O_APPEND,
0666) = -1 ENOENT (No such file or directory)

(in my test I set a wrong directory path in order to generate the
error).

I hope that may be helpful.

One more thing, as a side not.

You can try to write directly to the output stream using the '<<'
operator:

out << num << newLine.c_str() << std::endl;

Regards.
 
J

James Kanze

Ron Eggler wrote:

[...]
NEVER EVER EVER DECLARE A CHAR ARRAY ON STACK

There are exceptions. Rare, I'll admit, but they do exist.
AND THEN FILL IT WITH AN UNBOUND STRING.

That's where the danger is, of course. At the very least, he
needs an:
assert( newLine.size() + 1 < sizeof( str ) ;
"\n\r" is operating system specific. If you write that to some
platforms (MSVC) for example, you'll get more than one \r.

If he's on a Microsoft platform, I'm not surprised that he's
having trouble opening a file with the name "/usr/share/...".
(Technically, one could create such a directory under Windows,
but it would certainly be rare, and non conform to the Microsoft
conventions.)

What he probably wants to do is generate a file with fixed
conventions (corresponding the the ASCII standard). In which
case, he should open the file in binary mode. Technically, at
least---under Unix, of course, there's no difference.
What's wrong with:
std::string str = newLine + "\n";
?

Or: std::string str = newLine + "\n\r" ;, if that's what he
wants.
That code above will work correctly for any "newLine".
This is also endian dependant

Not just endian dependent, but totally undefined behavior.
First, of course, unless the file was opened in binary (and
imbued with "C"), who knows what will actually end up in the
file. And of course, floating point formats vary widely from
one machine to the next.
- not good depending on your use for the
output file. Are you really trying to write the bitwise representation
of the machine specific "double" type ?
If you're running under linux, try
touch /usr/share/NovaxTSP/INITreport.txt
Or run your program under strace and see what error you're
getting back from the OS.

If the directories leading up to the file exist, and he's
running as root, permissions shouldn't be a problem. At least
at the file level---even root can't write on a file system
mounted write protected. (A very long time ago, when the X/Open
group or the SysV people created /home, /var and /opt, the idea
was that /usr could be mounted write protected. For security
reasons, since this is where all of the critial parts of the
system reside as well. In practice, I've almost never seen it
done, because there were always programs which didn't conform to
the conventions, and wouldn't work if you couldn't write there.
Still, /usr/share is NOT a directory under which I would expect
to find a report.)
 
J

James Kanze

I'm trying to write to a text file with following code:
std::eek:fstream out("/usr/share/NovaxTSP/INITreport.txt", std::ios_base::in |
std::ios_base::eek:ut | std::ios_base::app);
if(!out) { // if out couldn't be opened, print error and exit
std::cout << "Cannot open reportfile:
\"/usr/share/NovaxTSP/INITreport.txt\"." << std::endl;
exit(0);
}
double num = 100.45;
char str[100];
strcpy(str, newLine.c_str());
strcat(str,"\n\r");
out.write((char *) &num, sizeof(double));
out.write(str, strlen(str));
out.close();
the folder /usr/share/NovaxTSP/ has permissions set to 775 and the
application is run as root but i still always get: Cannot open
reportfile: "/usr/share/NovaxTSP/INITreport.txt".
Why??? I don't understand, i made a df -h and there's enough space available
as well.
Does anyone have any other ideas on what to check?
I also touched the file before appending but that didn't change it either.
I tried to replicate your test environment, and it worked for me (I
had to comment out 'strcpy(str, newLine.c_str());', for newLine is not
defined).
You can try to run:
strace ./a.out
(a.out is your compiled executable).
You should get further information on the error near end of trace, for
example:
open("/usr/share/NovaxTSP/INITreport.txt", O_RDWR|O_CREAT|O_APPEND,
0666) = -1 ENOENT (No such file or directory)
(in my test I set a wrong directory path in order to generate the
error).

For that matter, he could just add strerror(errno) to his error
message (making sure to read errno before starting the output of
the error message). (And of course, such output belongs in
cerr, if not in a special log.)
 
R

Ron Eggler

Gianni said:
Ron said:
Hi,

I'm trying to write to a text file with following code:
std::eek:fstream out("/usr/share/NovaxTSP/INITreport.txt",
std::ios_base::in |
std::ios_base::eek:ut | std::ios_base::app);
if(!out) { // if out couldn't be opened, print error and exit
std::cout << "Cannot open reportfile:
\"/usr/share/NovaxTSP/INITreport.txt\"." << std::endl;
exit(0);
}
double num = 100.45;
char str[100];

NEVER EVER EVER DECLARE A CHAR ARRAY ON STACK

Alright, to not declare it on a stack, do i just declare it as a pointer?
like char *str; ?
AND THEN FILL IT WITH AN UNBOUND STRING.
Not sure what you mean exactly... sorry...
"\n\r" is operating system specific. If you write that to some
platforms (MSVC) for example, you'll get more than one \r.
I'm writing the code on a Linux system but I thought to make line breaks
Windows compatible i'll just do a \n\r instead of just a Unix \n, what's
wrong with that?
What's wrong with:
std::string str = newLine + "\n";
?

Okay, changed this...
That code above will work correctly for any "newLine".


This is also endian dependant - not good depending on your use for the
output file. Are you really trying to write the bitwise representation
of the machine specific "double" type ?

- Not really, this ws in there by mistake... :eek:
If you're running under linux, try

touch /usr/share/NovaxTSP/INITreport.txt

I have tried this - no success
Or run your program under strace and see what error you're getting back
from the OS.

how would i use strace, can you give me any assitance? I've never used it...

My code looks now like:
std::eek:fstream out("/usr/share/NovaxTSP/INITreport.txt", std::ios_base::in |
std::ios_base::eek:ut | std::ios_base::app);
if(!out) { // if out couldn't be opened, print error and exit
std::cout << "Cannot open reportfile:
\"/usr/share/NovaxTSP/INITreport.txt\"." << std::endl;
exit(0);
}
std::string str = newLine + "\n";
out.write(str, str.length());
out.close();

but it doesn't compile, the compiler is telling me:
.../gpsnmeareader.cpp:136: error: no matching function for call
to ‘std::basic_ofstream<char, std::char_traits<char> >::write(std::string&,
size_t)’
I'm not sure how I can get rid of this error so assitance would be
appreciated!
Thanks!
Ron
 
R

Ron Eggler

Ron said:
Gianni said:
Ron said:
Hi,

I'm trying to write to a text file with following code:
std::eek:fstream out("/usr/share/NovaxTSP/INITreport.txt",
std::ios_base::in |
std::ios_base::eek:ut | std::ios_base::app);
if(!out) { // if out couldn't be opened, print error and exit
std::cout << "Cannot open reportfile:
\"/usr/share/NovaxTSP/INITreport.txt\"." << std::endl;
exit(0);
}
double num = 100.45;
char str[100];

NEVER EVER EVER DECLARE A CHAR ARRAY ON STACK

Alright, to not declare it on a stack, do i just declare it as a pointer?
like char *str; ?
AND THEN FILL IT WITH AN UNBOUND STRING.
Not sure what you mean exactly... sorry...
"\n\r" is operating system specific. If you write that to some
platforms (MSVC) for example, you'll get more than one \r.
I'm writing the code on a Linux system but I thought to make line breaks
Windows compatible i'll just do a \n\r instead of just a Unix \n, what's
wrong with that?
What's wrong with:
std::string str = newLine + "\n";
?

Okay, changed this...
That code above will work correctly for any "newLine".


This is also endian dependant - not good depending on your use for the
output file. Are you really trying to write the bitwise representation
of the machine specific "double" type ?

- Not really, this ws in there by mistake... :eek:
If you're running under linux, try

touch /usr/share/NovaxTSP/INITreport.txt

I have tried this - no success
Or run your program under strace and see what error you're getting back
from the OS.

how would i use strace, can you give me any assitance? I've never used
it...

My code looks now like:
std::eek:fstream out("/usr/share/NovaxTSP/INITreport.txt",
std::ios_base::in |
std::ios_base::eek:ut | std::ios_base::app);
if(!out) { // if out couldn't be opened, print error and exit
std::cout << "Cannot open reportfile:
\"/usr/share/NovaxTSP/INITreport.txt\"." << std::endl;
exit(0);
}
std::string str = newLine + "\n";
out.write(str, str.length());
out.close();

but it doesn't compile, the compiler is telling me:
../gpsnmeareader.cpp:136: error: no matching function for call
to ‘std::basic_ofstream said:
::write(std::string&, size_t)’
I'm not sure how I can get rid of this error so assitance would be
appreciated!
Alright, nevermind this error, I'm just writing to the file by using the <<
operator:
out << newLine.c_str() << std::endl;
 

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

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top