How can I add new line to the file? [duplicate] - c++

This question already has an answer here:
How to writefile in new line in WIN32 API
(1 answer)
Closed 8 years ago.
I am using windows programming my project requires working with files I tried the following code
HANDLE hFile;
char DataBuffer[255] = "This is some test data to write to the file.";
DWORD dwBytesToWrite = (DWORD)strlen(DataBuffer);
DataBuffer[dwBytesToWrite+1]='\n';
DWORD dwBytesWritten = 0;
BOOL bErrorFlag = FALSE;
hFile = CreateFile(L"Myfile.txt", // name of the write
GENERIC_WRITE, // open for writing
0, // do not share
NULL, // default security
CREATE_ALWAYS, // create new file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL);
The below code was used add two lines to the file
bErrorFlag = WriteFile(
hFile, // open file handle
DataBuffer, // start of data to write
dwBytesToWrite, // number of bytes to write
&dwBytesWritten, // number of bytes that were written
NULL); // no overlapped structure
char DataBuffer1[] = "\n\nThe second line of code\n\n";
dwBytesToWrite=sizeof(DataBuffer1);
bErrorFlag = WriteFile(
hFile, // open file handle
DataBuffer1, // start of data to write
dwBytesToWrite, // number of bytes to write
&dwBytesWritten, // number of bytes that were written
NULL);
The program works fine but when i try to open "Myfile.txt" with the notepad i get the following results
" This is some test data to write to the file.The second line of code. "
Is there any other way to insert a new line to a file?

use \r\n instead of \n for newline.

instead of
char DataBuffer1[] = "\n\nThe second line of code\n\n";
Use
char DataBuffer1[] = "\r\nThe second line of code\r\n";

Related

Read 'Binary' files with ReadFile WinAPI

When I try to open '.exe' files with ReadFile() Windows API, It's just return the 2 first character of file like : MZ
Here is my Code:
#define BUFFERSIZE 5000
VOID CALLBACK FileIOCompletionRoutine(
__in DWORD dwErrorCode,
__in DWORD dwNumberOfBytesTransfered,
__in LPOVERLAPPED lpOverlapped
);
VOID CALLBACK FileIOCompletionRoutine(
__in DWORD dwErrorCode,
__in DWORD dwNumberOfBytesTransfered,
__in LPOVERLAPPED lpOverlapped)
{
_tprintf(TEXT("Error code:\t%x\n"), dwErrorCode);
_tprintf(TEXT("Number of bytes:\t%x\n"), dwNumberOfBytesTransfered);
g_BytesTransferred = dwNumberOfBytesTransfered;
}
HANDLE hFile;
DWORD dwBytesRead = 0;
char ReadBuffer[BUFFERSIZE] = { 0 };
OVERLAPPED ol = { 0 };
hFile = CreateFile(fullFilePath.c_str(), // file to open
GENERIC_READ, // open for reading
FILE_SHARE_READ, // share for reading
NULL, // default security
OPEN_EXISTING, // existing file only
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, // normal file
NULL); // no attr. template
ReadFileEx(hFile, ReadBuffer, BUFFERSIZE - 1, &ol, FileIOCompletionRoutine);
When I print ReadBuffer It's just MZ(exe file).
But Using:
std::ifstream file(argv[1], std::ios::in | std::ios::binary);
It's work perfectly.
How Can I Read Binary files With ReadFile?
The problem is not with reading, the problem is with printing.
You're not showing your code, but you're likely trying to print with printf or something similar. IOW, you're printing it as C string.
Well, binary data includes 0s, and in this case the first 3 bytes are 'M', 'Z', '\0' - and that prints as a null-terminated string "MZ".
You'd have to write a converter to per-byte hex numbers if you want to see meaningful printing of binary data: 4D 5A 00 and so on
How Can I Read Binary files With ReadFile?
ReadFile (and ReadFileEx ) works 'in binary mode'. You get exact file contents byte by byte without any translation.
You have problem with writing/printing. This mostly depends where you want to write, but for outputing (binary) data potentially containing nulls in C++ choose write method
some_output_stream.write( buffer_ptr, num_bytes_in_buffer );
some_output_stream should be set to binary mode (std::ios::binary). Without this flag all bytes with value 10 could be translated to pairs 13,10.
If C FILE functions are used
fwrite( buffer_ptr, 1, num_bytes_in_buffer, some_output_file );
Again some_output_file has to be in binary mode.
In some scenarios WriteFile can be used complementary to your usage of ReadFile.

Why does WriteFile not run more than once?

Here's my code in which I've got on an infinite loop (to my knowledge)
while(true) {
DWORD TitleID = XamGetCurrentTitleId();
std::ostringstream titleMessageSS;
titleMessageSS << "Here's the current title we're on : " << TitleID << "\n\n";
std::string titleMessage = titleMessageSS.str(); // get the string from the stream
DWORD dwBytesToWrite = (DWORD)titleMessage.size();
DWORD dwBytesWritten = 0;
BOOL bErrorFlag = FALSE;
HANDLE logFile = CreateFile( "Hdd:\\LOGFile.txt", GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
bErrorFlag = WriteFile(logFile, titleMessage.c_str(), dwBytesToWrite, &dwBytesWritten, NULL);
CloseHandle(logFile);
Sleep(30000);
}
return NULL;
Does anyone see a reason as to why this only writes just once? I've waited over 5 minutes to see if it does anything in the end to no avail.
The Flag CREATE_NEW in CreateFile prevents the update of the file because CreateFile fail with ERROR_FILE_EXISTS. Use OPEN_ALWAYS instead.
Also it will always truncate. Replace GENERIC_WRITE with FILE_APPEND_DATA if you want to add a new line at the end of your logfile.
The whole CreateFile line should be:
HANDLE logFile = CreateFile( "Hdd:\\LOGFile.txt", FILE_APPEND_DATA , 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
Read CreateFile documentation carefully, it worth it, because it has a central role in the windows IO universe:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
look also add:
https://stackoverflow.com/a/9891875/1922748
As Martin James mentioned, from MSDN:
CREATE_NEW
Creates a new file, only if it does not already exist.
If the specified file exists, the function fails and the last-error
code is set to ERROR_FILE_EXISTS (80).
If the specified file does not exist and is a valid path to a writable
location, a new file is created.
So it seems that the handle is invalid after the first call, and hence WriteFile() fails.

how to append text to a file in windows?

Everytime this function is called the old text data is lost?? Tell me how to maintain previous data and appending new data.
This function is called 10 times:
void WriteEvent(LPWSTR pRenderedContent)
{
HANDLE hFile;
DWORD dwBytesToWrite = ((DWORD)wcslen(pRenderedContent)*2);
DWORD dwBytesWritten = 0;
BOOL bErrorFlag = FALSE;
printf("\n");
hFile = CreateFile(L"D:\\EventsLog.txt", FILE_ALL_ACCESS, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("Terminal failure: Unable to open file \"EventsLog.txt\" for write.\n");
return;
}
printf("Writing %d bytes to EventsLog.txt.\n", dwBytesToWrite);
bErrorFlag = WriteFile(
hFile, // open file handle
pRenderedContent, // start of data to write
dwBytesToWrite, // number of bytes to write
&dwBytesWritten, // number of bytes that were written
NULL); // no overlapped structure
if (FALSE == bErrorFlag)
{
printf("Terminal failure: Unable to write to file.\n");
}
else
{
if (dwBytesWritten != dwBytesToWrite)
{
printf("Error: dwBytesWritten != dwBytesToWrite\n");
}
else
{
printf("Wrote %d bytes to EventsLog.txt successfully.\n",dwBytesWritten);
}
}
CloseHandle(hFile);
}
You should pass FILE_APPEND_DATA as the dwDesiredAccess to CreateFile, as documented under File Access Rights Constants (see sample code at Appending One File to Another File). While this opens the file using the correct access rights, your code is still responsible for setting the file pointer. This is necessary, because:
Each time a file is opened, the system places the file pointer at the beginning of the file, which is offset zero.
The file pointer can be set using the SetFilePointer API after opening the file:
hFile = CreateFile( L"D:\\EventsLog.txt", FILE_APPEND_DATA, 0x0, nullptr,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr );
if ( hFile == INVALID_HANDLE_VALUE ) {
printf( "Terminal failure: Unable to open file \"EventsLog.txt\" for write.\n" );
return;
}
// Set the file pointer to the end-of-file:
DWORD dwMoved = ::SetFilePointer( hFile, 0l, nullptr, FILE_END );
if ( dwMoved == INVALID_SET_FILE_POINTER ) {
printf( "Terminal failure: Unable to set file pointer to end-of-file.\n" );
return;
}
printf("Writing %d bytes to EventsLog.txt.\n", dwBytesToWrite);
bErrorFlag = WriteFile( // ...
Unrelated to your question, the calculation of dwBytesToWrite should not use magic numbers. Instead of * 2 you should probably write * sizeof(*pRenderedContent). The parameter to WriteEvent should be constant as well:
WriteEvent(LPCWSTR pRenderedContent)
The parameter for appending data to a file is FILE_APPEND_DATA instead of FILE_ALL_ACCESS in the CreateFile function.
Here is an example: http://msdn.microsoft.com/en-us/library/windows/desktop/aa363778(v=vs.85).aspx

Writing new line character in file

I just want write blank line into the file. i use following code but is not working.
char* RegID;
RegID = "10";
char* mndtime;
mndtime = "10";
char* resourcetype;
resourcetype = "Backup";
char* ressubtype;
ressubtype = "shadowprotect";
char* DataBuffer = new char[100];
StrCpy(DataBuffer,"<wpshadowprotectstatus>");
strcat(DataBuffer,"\n");
strcat(DataBuffer,"<mndtime>");
strcat(DataBuffer,RegID);
strcat(DataBuffer,"<\\mndtime>\n");
strcat(DataBuffer,"<resourcetype>");
strcat(DataBuffer,RegID);
strcat(DataBuffer,"<\\resourcetype>\n");
strcat(DataBuffer,"<ressubtype>");
strcat(DataBuffer,RegID);
strcat(DataBuffer,"<\\ressubtype>\n");
strcat(DataBuffer,"<jobname>");
strcat(DataBuffer,RegID);
strcat(DataBuffer,"<\\jobname>\n");
strcat(DataBuffer,"<jobstarttime>");
strcat(DataBuffer,RegID);
strcat(DataBuffer,"<\\jobstarttime>\n");
HANDLE hFile;
hFile = CreateFile("text.txt", // 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
if (hFile == INVALID_HANDLE_VALUE)
{
return 0;
}
DWORD dwBytesToWrite = (DWORD)strlen(DataBuffer);
DWORD dwBytesWritten = 0;
BOOL bErrorFlag = FALSE;
bErrorFlag = WriteFile(hFile, // open file handle
DataBuffer, // start of data to write
dwBytesToWrite, // number of bytes to write
&dwBytesWritten, // number of bytes that were written
NULL); // no overlapped structure
but i dont known why new line is not dump in text file.
Note :-
1)I dont want to use std:: library c++.
2)Dont want to use xml parser.
Use \r\n for line breaks on Windows.
And your XML is malformed. XML closing tags use the / character, not the \ character. And you are writing the same RegID variable for all of the XML values instead of using your other variables (mndtime, resourcetype, etc).
Windows?
If so, replace \n with \r\n. For FILE* / iostream it is done automatically by runtime, but not for WriteFile.
And, of course, you need two line endings to get blank line.
BTW, generating long string with strcat has O(N^2) complexity, which is very bad.

Write to a txt file using windows API

I am trying to write some lines to a a txt file through an ATL application. Below is the fragment of code I use:
HANDLE hFile = CreateFile(ofn.lpstrFile,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
DWORD dwBytesWritten = 0;
std::list<CString> helpList;
std::list<CString>::iterator it;
helpList.push_back(L"First Line\r\n");
helpList.push_back(L"Second Line");
for(it=helpList.begin(); it!=helpList.end(); ++it)
WriteFile( hFile, (*it).GetString(), (*it).GetLength(), &dwBytesWritten, NULL );
CloseHandle(hFile);
Notwithstanding everything is working right, nothing is finally written to the file. What should I change in the code?
Couple of issues:
Close the handle to the file using CloseHandle()
The length argument for WriteFile() is in bytes but you're specifying characters. Since you're using wide chars you need to multiple the length value by the size of the char.