Click here to Skip to main content
16,021,294 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi guys,
I am really confuse now what to do with \n and \r\n charecters.I am reading and writing some files in c++.
Basically i want to maintain log file of one exe where following conditions are consider.
1)If file is not present then create file.
2)If file is already present then append data on it.

But some reason it not working following are some block of code i am using.
to open a file i am using following code.
C++
bool ApplicationfileNotOpen;	
char* ApplicationFileLogName;
ApplicationFileLogName = ".\\ApplicationLog\\Sample.log";
HANDLE APllicationLogWriteHandle;
APllicationLogWriteHandle = CreateFile(ApplicationFileLogName, // name of the write
				    GENERIC_WRITE,          // open for writing
				    0,                      // do not share
				    NULL,                   // default security
				    CREATE_NEW,             // create new file only
				    FILE_ATTRIBUTE_NORMAL,  // normal file
				    NULL);                  // no attr. template


To write a data in file i am using following code..
C++
char MessageString[200];
MessageString = "Application Start \n";
time_t ApplicationNow = time(NULL);
ApplicationNow = time(NULL);
struct tm * timeinfo = localtime(&ApplicationNow);
char Applicationtimstring[100];
strftime (Applicationtimstring,32,"%d/%m/%Y %I:%M:%S %p",timeinfo);

char Temp_Char_Array[DEFAULT_ARRAY_SIZE];
StrCpy(Temp_Char_Array,Applicationtimstring);
StrCat(Temp_Char_Array,  MessageString);
DWORD dwBytesToWrite = (DWORD)strlen(Temp_Char_Array);
DWORD dwBytesWritten = 0;
BOOL bErrorFlag = FALSE;
bErrorFlag=WriteFile(ApplicationFileHandle, // open file handle
		   Temp_Char_Array,      // start of data to write
		   dwBytesToWrite,  // number of bytes to write
		   &dwBytesWritten, // number of bytes that were written
		   NULL);            // no overlapped structure


and for reading from file i am using following code.
C++
//To open file
char* ApplicationFileLogName;
ApplicationFileLogName = ".\\ApplicationLog\\Sample.log";
FILE *ApplicationfileOpenHandle;
 ApplicationfileOpenHandle =fopen(ApplicationFileLogName,"r");

//Read file..
while(fgets(CurrentString , DEFAULT_ARRAY_SIZE , ApplicationfileOpenHandle) != NULL)//Reading one by one line from file it UNICODE..
{
     	printf("%s",CurrentString);
}

Now when i open file "sample.log" in notpad it will show me following content all in same line.
10/05/2013 02:32:28 PM Application Start 10/05/2013 02:32:36 PM Application Start 10/05/2013 02:47:31 PM Application Start

All in same line but when i open it in wordpad or textpad it will show me all content proper like,
10/05/2013 02:32:28 PM Application Start
10/05/2013 02:32:36 PM Application Start
10/05/2013 02:47:31 PM Application Start

please tell me where i am going wrong.
Note :- i already use \r\n but its not working.
Posted

On Windows system newline is "\r\n" (see, for instance Wikipedia[^]). Hence it should work (you should see proper output on notepad, other applications are able to render text file with other newline conventions).
Please check (with the help of an hex editor) the actual file content.
 
Share this answer
 
Comments
Coder Block 13-May-13 0:47am    
your the gem thank you so much..
In your code, you are using this output:

MessageString = "Application Start \n";


You are using only a newline.
Add the \r and it should work as you expect.
 
Share this answer
 
As has already been said, Windows Notepad expects a carriage return-line feed pair (\r\n). There is, however, no other reason to stick to this out-dated method of ending a line (invented due to the slowness of the tele-type machine of the day) but you do need to know about it for reading text files since so many still use it.

If you want to see more accurately what is in the file you are writing, try something like Notepad++[^], which will interpret CR, LF, or a CRLF pair, as a new line, and you can also switch on display of these characters (and also all white space characters) from the menu (View->Show Symbol).

Out of interest, how come you are using the Windows API functions (CreateFile ...) to write the file, but the C functions (fopen ...) to read it? I'd stick with one or the other. If the app is being compiled for use only on Windows, go with the Windows API functions.
Thus you might open a file for reading like this:
C++
HANDLE ApplicationfileOpenHandle = ::CreateFile(ApplicationFileLogName, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
// Check ApplicationfileOpenHandle against INVALID_HANDLE_VALUE.
// If equal, get the last windows error, and perhaps throw an exception.
If insisting on using the fopen/fgets option, for VC++ at least consider using the more secure function fopen_s[^].

However, I note that you have a comment against your fgets line that the file is Unicode, but you don't appear to be reading it as if it is Unicode, nor converting correctly from whatever the Unicode encoding is into your multi-byte string. So this is another area you may need to look at.

The down-side of the Windows API functions is a there is no obvious function to read a line. This is my method (but again, this is not for Unicode - you will have to work that one out yourself if you really need it):
std::string ReadLine
  (
  HANDLE theFile
  )
{
  if (INVALID_HANDLE_VALUE == theFile)
  {
    // Throw exception
  }

  std::string result;
  char readChar = 0;
  const DWORD numberOfBytesToRead = sizeof(readChar);
  DWORD numberOfBytesRead = 0;

  do
  {
    BOOL readResult = ::ReadFile(theFile, &readChar,
                         numberOfBytesToRead, &numberOfBytesRead, NULL);
    if (FALSE == readResult)
    {
      // Read failed: throw an exception.  Use ::GetLastError() to obtain
      // the reason for failure to include in the exception.
    }
    // If the return value is nonzero and the number of bytes read is 0 (zero),
    // the file pointer is beyond the current end of the file at the time of
    // the read operation.
    if (numberOfBytesRead > 0)
    {
      if (readChar == '\r')
      {
        // Ignore any carriage returns and continue looking for line feed.
        // I.e. nothing to do here.
        // We can only do this on Windows (or certain Unix) machines,
        // because other Operating Systems (such as MacOS) use \r alone as
        // their end of line character, instead of \n or \r\n.
      }
      else if (readChar == '\n')
      {
        // End of line is reached
        break;
      }
      else
      {
        // Any other character can be added to the return string
        result += readChar;
      }
    }
  } while(numberOfBytesRead > 0);

  return result;
}
Regards,
Ian.
 
Share this answer
 
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900