erondem
erondem

Reputation: 582

How to write to .txt file without recreating existing file

I have basic logging process. When an error occured in the program, it has to been logging to a .txt file. I use following code for this:

#include <fstream> 

fileName = "logs/error_log.txt";
ofstream myfile;
myfile.open (fileName,fstream::app);
myfile << serialized_string << endl;
myfile.close();

When an error occured it goes to error_log.txt file successfully. But when program crashed and is restarted afterward, new logs are not logged as append. As expected the way I am using creates a new file which has same name existed file and write on it. Can someone explain me how should I write older logs as well?

Edit: These are steps I have faced: I am using raspbian and I compile with following:

g++ main.cpp -lwiringPi -lpthread -lcurl -o test

That is the whole function.

int putLog(const char* process, int logType, string logData) {
  isLoggerBusy = true;
  string fileName;
  std::string color;
  switch (logType) {
    case 0:
      fileName = "logs/error_log.txt";
      // color = "\033[0;31m";
      break;

    case 1:
      fileName = "logs/info_log.txt";
      //    color = "\033[0;36m";
      break;

    case 2:
      fileName = "logs/state_log.txt";
      //    color = "\033[1;33m";
      break;
  }

  if (process == "WebSocket") {
    color = "\033[1;32m";
  }

  json j = {
      {"Process", process}, {"Time", currentDateTime()}, {"Log", logData}};

  string serialized_string = j.dump();
  fix_utf8_string(serialized_string);

  ofstream myfile;
  myfile.open(fileName, fstream::app);
  cout << color << serialized_string << '\n';
  myfile << serialized_string << endl;
  myfile.close();
  isLoggerBusy = false;
  cout << "\033[0m" << endl;
  return 0;
}

{"Log":"Incoming Message{\"Action\":\"Heartbeat\",\"Data\":null}","Process":"WebSocket","Time":"2018-08-16.14:53:52"}

{"Log":"GSM Setup Finished","Process":"SMSService","Time":"2018-08-16.14:54:13"}

Upvotes: 4

Views: 369

Answers (1)

Scheff&#39;s Cat
Scheff&#39;s Cat

Reputation: 20141

I cannot reproduce what OP describes.

I just tested on cygwin/Windows 10. (I didn't know how to make this test on an online compiler.)

testFStreamApp.cc:

#include <iostream>
#include <fstream>

int main()
{
  std::cout << "Log error...\n";
  { std::ofstream log("testFStream.log", std::ios::out | std::ios::app);
    log << "Error happened!" << std::endl;
  }
  std::cout << "Going to die...\n";
  abort();
  return 0; // should never be reached
}

Test Session:

$ g++ -std=c++11 -o testFStreamApp testFStreamApp.cc 

$ rm testFStream.log

$ for i in 1 2 3; do  
> echo "$i. start:"
> ./testFStreamApp 
> done
1. start:
Log error...
Going to die...
Aborted (core dumped)
2. start:
Log error...
Going to die...
Aborted (core dumped)
3. start:
Log error...
Going to die...
Aborted (core dumped)

$ cat <testFStream.log 
Error happened!
Error happened!
Error happened!

$

YSC pointed out that I made some silent changes. I did it assuming no relevance.

However, to erase any excuses, I tried also:

#include <iostream>
#include <fstream>

int main()
{
  std::cout << "Log error...\n";
  std::ofstream log;
  log.open("testFStream.log", std::fstream::app);
  log << "Error happened!" << std::endl;
  log.close();
  std::cout << "Going to die...\n";
  abort();
  return 0; // should never be reached
}

The output was exactly as above.


I hadn't dared to test this but doctorlove encouraged me:

#include <iostream>
#include <fstream>

int main()
{
  std::cout << "Log error...\n";
  std::ofstream log;
  log.open("testFStream.log", std::fstream::app);
  log << "Error happened!" << std::endl;
  std::cout << "Going to die...\n";
  abort();
  log.close();  
  return 0; // should never be reached
}

Even in this case, I got the same result.

At this point, I must admit that cygwin is just a wrapper around the win32 API. So, in this case, I wouldn't wonder if this behaves different on other OSes.

I'm aware that std::endl does a flush() insight. The question is how far down (into the system) the flush() is effective. (In daily work, I try to write the code in a way that it is not necessary to rely on such details...) ;-)

Upvotes: 4

Related Questions