ofstream problem

Discussion in 'C++' started by Ron Eggler, Feb 23, 2008.

  1. Ron Eggler

    Ron Eggler Guest

    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
     
    Ron Eggler, Feb 23, 2008
    #1
    1. Advertising

  2. Ron Eggler wrote:
    > 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.
     
    Gianni Mariani, Feb 23, 2008
    #2
    1. Advertising

  3. Ron Eggler

    Guest

    On Feb 23, 1:33 am, Ron Eggler <> wrote:
    > 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.
     
    , Feb 23, 2008
    #3
  4. Ron Eggler

    James Kanze Guest

    On Feb 23, 2:01 am, Gianni Mariani <> wrote:
    > Ron Eggler wrote:


    [...]
    > > char str[100];


    > NEVER EVER EVER DECLARE A CHAR ARRAY ON STACK


    There are exceptions. Rare, I'll admit, but they do exist.

    > > strcpy(str, newLine.c_str());


    > 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 ) ;

    > > 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.


    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".


    > > out.write((char *) &num, sizeof(double));


    > 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 ?


    > > 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.


    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.)

    --
    James Kanze (GABI Software) email:
    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
     
    James Kanze, Feb 23, 2008
    #4
  5. Ron Eggler

    James Kanze Guest

    On Feb 23, 2:23 am, wrote:
    > On Feb 23, 1:33 am, Ron Eggler <> wrote:


    > > 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.)

    --
    James Kanze (GABI Software) email:
    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
     
    James Kanze, Feb 23, 2008
    #5
  6. Ron Eggler

    Ron Eggler Guest

    Gianni Mariani wrote:

    > Ron Eggler wrote:
    >> 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; ?
    >
    >> strcpy(str, newLine.c_str());

    >
    > AND THEN FILL IT WITH AN UNBOUND STRING.

    Not sure what you mean exactly... sorry...
    >
    >> 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.

    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".
    >
    >> 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 ?


    - Not really, this ws in there by mistake... :eek:
    >
    >> 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


    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
     
    Ron Eggler, Feb 25, 2008
    #6
  7. Ron Eggler

    Ron Eggler Guest

    Ron Eggler wrote:

    > Gianni Mariani wrote:
    >
    >> Ron Eggler wrote:
    >>> 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; ?
    >>
    >>> strcpy(str, newLine.c_str());

    >>
    >> AND THEN FILL IT WITH AN UNBOUND STRING.

    > Not sure what you mean exactly... sorry...
    >>
    >>> 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.

    > 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".
    >>
    >>> 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 ?

    >
    > - Not really, this ws in there by mistake... :eek:
    >>
    >>> 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

    >
    > 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!

    Alright, nevermind this error, I'm just writing to the file by using the <<
    operator:
    out << newLine.c_str() << std::endl;

    > Thanks!
    > Ron
     
    Ron Eggler, Feb 25, 2008
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Tom Johnson
    Replies:
    4
    Views:
    397
    red floyd
    Aug 15, 2003
  2. Armando
    Replies:
    2
    Views:
    7,144
    Martijn Lievaart
    Jan 23, 2004
  3. slyphiad

    ofstream problem

    slyphiad, Sep 14, 2004, in forum: C++
    Replies:
    2
    Views:
    2,102
    Mike Wahler
    Sep 14, 2004
  4. Alfons
    Replies:
    1
    Views:
    464
  5. Squid Seven

    ofstream * vs. ofstream

    Squid Seven, Jul 13, 2005, in forum: C++
    Replies:
    5
    Views:
    631
    Ivan Johansen
    Jul 14, 2005
Loading...

Share This Page