C++ newline fails diff test? - c++

So I have a two programs that I am comparing output to. Whenever it does a newline, it says my output is different using a diff utility.
I have tried using:
std::cout << endl;
and
std::cout << '\n';
but it winmerge still says that our output is different. I am running both executables on the same machine.

Streaming std::endl is equivalent to streaming '\n' then std::flush so, no, you won't see any differences. More likely your tool is expecting to find a Windows-style line ending (that is, CRLF rather than just LF).
std::cout << "\r\n" << std::flush;
But, instead of guessing, you should simply open up that comparison data in a hex editor and see for yourself what characters are expected.

Read the file in binary mode and check the byte values for the newline.
One will probably be a char with ASCII code 10
and the other will be 10 and 13.

Related

WriteFile function with assembly debugging (syncing)

First of all, this question is based on my last question here: Reading Console Buffer / Output C++
I have a compiled executable binary file. It has some outputs, what I would like to redirect it to an other program, that handles the lines. I successfully found where the output is sent, and I modified it to STDOUT. The problem is that, when I use it like:
./jampDed.exe | stdout.exe
then the output is not synced. I got the content after every 1000-2000 bytes.
stdout.cpp
#include <iostream>
int main() {
std::string s;
while (std::getline(std::cin, s, '\n')) {
std::cout << s << std::endl;
}
return 0;
}
I also created a picture about assembly modification, where Kernel32.WriteFile function was used by default.
So the question is that, how can I make it synced? How to get every line as soon as it happens on the dedicated server?
Somewhere in the executable where it establishes stdout is an option bit for unbuffered output. Just set (or clear) that bit. Then every call to write is transferred without delay. This adds significant execution time and i/o system effort to that program but is probably okay for this.
The program which processes that output (as input) should buffer full lines because the program is unlikely to do full line output itself.
Why don't you try:
std::cout << s << std::endl << std::flush;
^^^^^^^^^^

comparison of strings does not work

I have a code as below. Whenever temps = $Nodes loop should end. I checked temps every in iteration and saw that temps = $Nodes once as expected but the loop was not ended. This code worked for VS10 but not working for linux. Any idea?
std::string temps;
s_mesh_file.open (mesh_file.c_str());
do
{
getline (s_mesh_file, temps);
std::cout << "temps: " << temps << std::endl;
std::cin.ignore();
}
while (temps != "$Nodes");
Are they using the same exact input file? Including with Windows newlines? Linux doesn't like windows newlines. (Nor does Windows like Linux's)
In windows, each newline is a \r followed by an \n. In Linux, a newline is just \n. Streams open by default in "text mode" which converts whatever the system newline is into just \n. So, when you read the file in Windows, it's dropping the \r helpfully. However, Linux doesn't realize it's part of the newline, and so is putting the \r onto the end of your string like any other normal character, which makes it not match the hardcoded "$Nodes".
Remove std::cin.ignore();. You are waiting for user input actually. Tested on linux.

How to change EOL coding in txt files?

I am writing in Visual Studio 2008 in C++ and I have problems with other libraries - they do not accept the line endings (EOL) I generate with my txt files.
How can I change that while writing a file with
std::ofstream myFile;
myFile.open("traindata.txt");
myFile << "stuff" << endl;
// or
//myFile << "stuff" << '\n';
myFile.close();
EDIT 2 :
Ok, I did a mistake in code : I was appending "0 " for every iteration so that I had whitespace before the EOL.
By bad. You guys have been right. Thanks for help.
Is it possible that you just don't want the \n to end of line sequence to happen? Open your file using std::ios_base::binary: this turns off precisely the conversion. ... and don't use std::endl unless you really want to flush the stream:
std::ofstream myFile("traindata.txt", std::ios_base::binary);
myFile << "stuff\n";
The close() is typically also unnecessary unless you want to check that it was successful.
You should open the file stream in binary mode to keep C++ library from converting line endings automatically:
myFile.open("traindata.txt", std::ios_base::out|std::ios_base::binary);
That will keep C++ library from converting '\n' to OS-specific EOL symbol (CR-LF on Windows).
Download notepad++ - that should be able to fix the problem.
Or dos2unix, unix2dos on cygwin
Use myfile << "\r\n" for the Windows-style ending, or myfile << "\n" for the UNIX-style.

Rewinding std::cout to go back to the beginning of a line

I'm writing a command-line tool for Mac OS X that processes a bunch of files. I would like to show the user the current file being processed, but do not want a bazillion files polluting the terminal window.
Instead I would like to use a single line to output the file path, then reuse that line for the next file. Is there a character (or some other code) to output to std::cout to accomplish this?
Also, if I wanted to re-target this tool for Windows, would the solution be the same for both platforms?
"\r" should work for both windows and Mac OS X.
Something like:
std::cout << "will not see this\rwill see this" << std::flush;
std::cout << std::endl; // all done
I don't have access to a mac, but from a pure console standpoint, this is going to be largely dependent on how it treats the carriage return and line-feed characters. If you can literally send one or the other to the console, you want to send just a carriage return.
I'm pretty sure Mac treats both carriage returns and line-feeds differently than *nix & windows.
If you're looking for in-place updates (e.g. overwrite the current line), I'd recommend looking at the curses lib. This should provide a platform independent means of doing what you're looking for. (because, even using standard C++, there is no platform independent means of what you're asking for).
As Nathan Ernst's answer says, if you want a robust, proper way to do this, use curses - specifically ncurses.
If you want a low-effort hackish way that tends to work, carry on...
Command-line terminals for Linux, UNIX, MacOS, Windows etc. tend to support a small set of basic ASCII control characters, including character 13 decimal - known as a Carriage Return and encoded in C++ as '\r' or equivalently in octal '\015' or hex '\x0D' - instructing the terminal to return to the start of the line.
What you generally want to do is...
int line_width = getenv("COLUMNS") ? atoi(getenv("COLUMNS")) : 80;
std::string spaces{line_width - 1, ' '};
for (const auto& filename : filenames) {
std::cout << '\r' << spaces << '\r' << filename << std::flush;
process_file(filename);
}
std::cout << std::endl; // move past last filename...
This uses a string of spaces to overwrite the old filename before writing the next one, so if you have a shorter filename you don't see trailing characters from the earlier longer filename(s).
The std::flush ensures the C++ program calls the OS write() function to send the text to the terminal before starting to process the file. Without that, the text needed for the update - \r, spaces, \r and a filename - will be appended to a buffer and only written to the OS - in e.g. 4k chunks - when the buffer is full, so the filename displayed would lag dozens of files behind the actual file being processing. Further, say the buffer is 4k - 4096 bytes - and at some point you have 4080 bytes buffered, then output text for the next filename: you'll end up with \r and 15 spaces fitting in the buffer, which when auto-flushed will end up wiping out the first 15 characters on the line on-screen and leaving the rest of the previous filename (if it was longer than 15 characters), then waiting until the buffer is full again before updating the screen (still haphazardly).
The final std::endl just moves the cursor on from the line where you've been printing filenames so you can write "all done", or just leave main() and have the shell prompt display on a nice clean line, instead of potentially overwriting part of your last filename (great shells like zsh check for this).

what does std::endl represent exactly on each platform?

Thinking about UNIX, Windows and Mac and an output stream (both binary and text),
What does std::endl represent, i.e. <CR><LF>, <LF> or <CR>? Or is it always the same no matter what platform/compiler?
The reason I'm asking is that I'm writing a TCP client that talks a protocol that expects each command to end in <CR><LF>. So I'm wondering whether to use std::endl or "\r\n" in my streams.
EDIT: Ok, so one flushes the buffer and another doesn't. I get that. But if I'm outputting text to a file, is '\n' equal to <LF> or does it convert to <CR><LF> on Windows and <LF> on Unix or not? I don't see a clear answer yet.
The code:
stream << std::endl;
// Is equivalent to:
stream << "\n" << std::flush;
So the question is what is "\n" mapped too.
On normal streams nothing happens. But for file streams (in text mode) then the "\n" gets mapped to the platfrom end of line sequence. Note: The read converts the platform end of line sequence back to a '\n' when it reads from a file in text mode.
So if you are using a normal stream nothing happens. If you are using a file stream, just make sure it is opened in binary mode so that no conversion is applied:
stream << "\r\n"; // <CR><LF>
The C++ standard says that it:
Calls os.put(os.widen(ā€™\nā€™) ), then
os.flush()
What the '\n' is converted to, if it is converted at all, is down to the stream type it is used on, plus any possible mode the stream may be opened in.
Use stream << "\r\n" (and open the stream in binary mode). stream << std::endl; is equivalent to stream << "\n" << flush;. The "\n" might be converted to a "\r\n" if the code runs on Windows, but you can't count on it -- at least one Windows compiler converts it to "\n\r". On a Mac, it's likely to be converted to "\r" and on Unix/Linux and most similar systems, it'll be left as just a "\n".
Quoted from the accepted answer on a related question:
The varying line-ending characters don't matter, assuming the file is open in text mode, which is what you get unless you ask for binary. The compiled program will write out the correct thing for the system compiled for.
The only difference is that std::endl flushes the output buffer, and '\n' doesn't. If you don't want the buffer flushed frequently, use '\n'. If you do (for example, if you want to get all the output, and the program is unstable), use std::endl
In your case, since you specifically want <CR><LF>, you should explicitly use \r\n, and then call std::flush() if you still want to flush the output buffer.
Looks like your question got munged. Each command ends in []? For an over-the-wire protocol, I'd suggest using a delimiter that doesn't vary by platform. std::endl could resolve to '\r\n' or '\n\r' depending on the platform.