strange cout behaviour - c++

I compiled on Ubuntu a program that was developed for (and works on) Windows. On Ubuntu, I see this code:
string s = values_[9];
cout << s << endl;
cout << s << "x\n";
producing this output:
high
xigh
The expected output for the second line is "highx". I know that the value of values_[9] is originally read from a file (written on Windows). Printing other strings seems to work normally.
What's going on here?

Run the command with its output piped through cat -A. Probably either the value of s, or the output produced by endl is giving you a '\r' character, which typically sends the cursor back to the beginning of the line.
EDIT: On further thought, the stray '\r' is almost certainly in s, not in the output produced by endl. I had thought there might be some funny locale stuff going on, but having s equal to "high\r" explains the symptoms.
EDIT2: If your system doesn't have cat -A (it's a GNU extension), try cat -v or, if you're desperate, od -c.

The string you're printing has a carriage return '\r' in it. What's happening is that you're printing high, then the carriage return, which puts the cursor back on the start of the line. Then, when you print the x, it overwrites the first letter on the line.
You should either remove the carriage return from the source file (e.g. with dos2unix(1) or many other options), or change your code to strip the carriage return after reading the file in.

What is probably happening, is that there is a \r in values_[9].

Related

How do I rewrite a line of text in a console project? c++

I'm working on a c++ console project and i would like to show a percentage without making a new line each time (so that the window doesn't get clogged with thousands of lines).
Is there a way of removing the last line that was printed or something to say that the next time that i output a line it should replace the current line?
You can use a \r (carriage return) to return the cursor to the beginning of the line:
This works on windows and Linux.
From: Erase the current printed console line
You could alternatively use a series of backspaces.
string str="Hello!";
cout << str;
cout << string(str.length(),'\b');
cout << "Hello again!";
From: http://www.cplusplus.com/forum/unices/25744/
Maybe mark as duplicate? I am really not sure how.
A simple example that I tested on Linux would be:
std::cout << "Some text to display..." << "\t\r" << std::flush;
Here the \t adds a tabulation to handle slightly varying string lengths and \r sends the cursor back at the start of the line (as mentioned in other answers).
std::flush is required to guarantee that the line is displayed without jumping to the next line.
This is very platform-dependent and terminal-dependent. But, you may want to look at ncurses for a start: http://linux.die.net/man/3/ncurses
For Windows: How can I overwrite the same portion of the console in a Windows native C++ console app, without using a 3rd Party library?
For Linux: https://unix.stackexchange.com/questions/43075/how-to-change-the-contents-of-a-line-on-the-terminal-as-opposed-to-writing-a-new

C++ Opening file with *i pointer, Overrides in Linux but not in Windows

So I've got this program working in Windows, and I'm trying to make it also work on a Linux machine. I believe the Linux machine is running an outdated version of g++ compiler but that is out of my control. Anyway, heres my function:
for (vector<string>::iterator i = groups.begin(); i != groups.end(); ++i)
{
inStream.open((*i + "List.txt").c_str());
while (getline(inStream, next))
{
if (next == n) {
memberOf.push_back(*i);
}
}
inStream.close();
}
The issue lies with the inStream.open() call. In windows this works fine, but in Linux it seems that *i (for example lets say that *i is pointing to "Tigers") is being overridden and therefore the call is just inStream.open("List.txt"); as opposed to inStream.open("TigersList.txt");
I've tried various ways of solving this, such as setting string k = *i; which works in itself in the sense that if I call cout << k; it prints "Tigers". However as soon as I try to concatenate "List.txt" to the end it just overrides "Tigers" and I'm left with only "List.txt"
ex:
k += "List.txt";
k.append("List.txt");
etc. Nothing seems to work in Linux, however everything I've tried has the same (correct) end result in windows.
What am I doing wrong???
Edit: inStream is an ifStream object.
memberOf is another vector of strings.
It sounds like you are reading Tigers from a file that contains Windows line endings. If you read this file in Linux, then reading the line:
Tigers\r\n
will result in your string in memory being Tigers\r. Then when you concatenate to it, even though the result actually ends up being Tigers\rList.txt, when you print it out then your terminal treats \r as carriage return and so List.txt overwrites Tigers on your screen.
Of course, opening the file fails because the filename didn't contain an embedded \r.
To fix this you could do one of the following:
In Linux, make sure that the file you're opening has Linux line endings (e.g. run dos2unix on it)
Update your program to look for and discard a \r on the end of a line that it has read from the file.

Strange stdout behavior

I'm currently writing a socket program in C++ and I've stumbled across very strange behavior when trying to write to the console (a required task), for some reason.
cout << themsg[0] << themsg[1] << endl;
cout << "Phase 3: Supernode sent the message " << themsg[0] << " on dynamic port number " << themsg[1] << endl;
themsg[0] is the string "User#2:What's up Dick?"
themsg[1] is the string "39416"
The first line should write "User#2:What's up Dick?" to the console, followed by "39416".
The second line should print "Phase 3: Supernode sent the message User#2:What's up Dick? on dynamic port number 39416"
The console output reads as follows:
394162:What's up Dick?
on dynamic port number 39416essage User#2:What's up Dick?
I know that themsg[0] and themsg[1] are correct because I wrote their values to a file for verification. It surely has to be some weird stdout issue.
For the first line it appears the 5 characters of themsg[1] overwrite the first five characters of themsg[0]. For the second line, it appears that the first two parameters for cout are ignored, and then there is a message fragment appended.
If anyone can help, I would really appreciate it. I tried using flush() but to no avail. I'm not really sure how the output buffer works, so I'm really lost with this.
You probably have a carriage return symbol, \r, at the end of themsg[0]. I can reproduce the behavior with the following program on Linux:
int main()
{
std::cout << "User#2: what's up?\r" << "39416" << std::endl;
}
The \r, when not followed by \n, has the effect of returning the virtual "carriage" of the terminal to the beginning of the line, so the next print will overwrite what was already there. You won't see this showing up in a file, though, as the file will just contain both strings including the CR.
Strip off the \r before printing.
I suspect the problem is in your themes variable. I tested your exact setup - and, with proper values, it works correctly. However I then tested the same setup but appended \r to the end of themsg[1] and themsg[2] - and got exactly your behaviour. As your string themsg[1] is coming from the network, it probably has line ending included - and from a different operating system (e.g. UNIX vs Windows) - this is converted to a carriage return without the line feed - resulting in the behaviour you're seeing.

What's the Use of '\r' escape sequence?

I have C code like this:
#include<stdio.h>
int main()
{
printf("Hey this is my first hello world \r");
return 0;
}
I have used the \r escape sequence as an experiment. When I run the code I get the output as:
o world
Why is that, and what is the use of \r exactly?
If I run the same code in an online compiler I get the output as:
Hey this is my first hello world
Why did the online compiler produce different output, ignoring the \r?
\r is a carriage return character; it tells your terminal emulator to move the cursor at the start of the line.
The cursor is the position where the next characters will be rendered.
So, printing a \r allows to override the current line of the terminal emulator.
Tom Zych figured why the output of your program is o world while the \r is at the end of the line and you don't print anything after that:
When your program exits, the shell prints the command prompt. The terminal renders it where you left the cursor. Your program leaves the cursor at the start of the line, so the command prompt partly overrides the line you printed. This explains why you seen your command prompt followed by o world.
The online compiler you mention just prints the raw output to the browser. The browser ignores control characters, so the \r has no effect.
See https://en.wikipedia.org/wiki/Carriage_return
Here is a usage example of \r:
#include <stdio.h>
#include <unistd.h>
int main()
{
char chars[] = {'-', '\\', '|', '/'};
unsigned int i;
for (i = 0; ; ++i) {
printf("%c\r", chars[i % sizeof(chars)]);
fflush(stdout);
usleep(200000);
}
return 0;
}
It repeatedly prints the characters - \ | / at the same position to give the illusion of a rotating | in the terminal.
The program is printing "Hey this is my first hello world ", then it is moving the cursor back to the beginning of the line. How this will look on the screen depends on your environment. It appears the beginning of the string is being overwritten by something, perhaps your command line prompt.
The '\r' stands for "Carriage Return" - it's a holdover from the days of typewriters and really old printers. The best example is in Windows and other DOSsy OSes, where a newline is given as "\r\n". These are the instructions sent to an old printer to start a new line: first move the print head back to the beginning, then go down one.
Different OSes will use other newline sequences. Linux and OSX just use '\n'. Older Mac OSes just use '\r'. Wikipedia has a more complete list, but those are the important ones.
Hope this helps!
PS: As for why you get that weird output... Perhaps the console is moving the "cursor" back to the beginning of the line, and then overwriting the first bit with spaces or summat.
\r move the cursor to the begin of the line.
Line breaks are managed differently on different systems. Some only use \n (line feed, e.g. Unix), some use (\r e.g. MacOS before OS X afaik) and some use \r\n (e.g. Windows afaik).
As amaud576875 said, the \r escape sequence signifies a carriage-return, similar to pressing the Enter key. However, I'm not sure how you get "o world"; you should (and I do) get "my first hello world" and then a new line. Depending on what operating system you're using (I'm using Mac) you might want to use a \n instead of a \r.
This is from antiquated technology: The old fashion typewriter style of printer. There was a roller (platen) that advanced the paper and a print head that hammered a metal key against an ink fabric.
\r Return the print head to the left side.
\n Advance the platen one line.
If the \n was not issued, you would type over what was on a line (used mostly for underlining text).
To answer the part of your question,
what is the use of \r?
Many Internet protocols, such as FTP, HTTP and SMTP, are specified in terms of lines delimited by carriage return and newline. So, for example, when sending an email, you might have code such as:
fprintf(socket, "RCPT TO: %s\r\n", recipients);
Or, when a FTP server replies with a permission-denied error:
fprintf(client, "550 Permission denied\r\n");
It is quite useful, when you are running on the unix platform, and need to create a text file
which will be opened on the dos platform.
Unix uses '\n' as its line terminator, and dos uses '\r\n' as its line terminator, so you can use it to create a dos text file.

"No newline at end of file" warning, even after putting in a newline [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I've been trying to learn C++ lately, and all has been going well until today. I'm trying to make a very simple application that basically just asks a user for a number and then displays the factorial of that number.
When I try to compile the file in Cygwin (g++ factorial.cpp -o fact), I get the following warning "warning: no newline at end of file". Following the words of the warning, I added a newline at the end of the file and tried it again...with the exact same result. Whether I try one newline or twenty, it never seems to compile.
I attached the simple, and still unfinished, file below (Except imagine there is a blank line at the end of it. This noob can't get it show up in code view):
#include <iostream>
#include <string>
using namespace std;
int getInput();
void displayFactorial(int);
int main()
{
int number = getInput();
displayFactorial(number);
return 0;
}
int getInput()
{
int userNumber;
bool okNumber;
while(okNumber == false){
cout << "Please eneter a number in the range of 1-10";
cin >> userNumber;
if(userNumber >= 1 and userNumber <=10){
okNumber = true;
}
else{
cout << "Incorrect number" << endl;
}
}
return userNumber;
}
void displayFactorial(int number){
string displayString = number + "! =";
int total;
for(int i = 0; i<=number; i++){
//displayString += "
}
cout << displayString;
}
// File ended the line above this (with a new line. This line added by Martin so it shows)
Any idea what could cause that warning if it's not the newline?
First of all a warning does not prevent a program from compiling.
Second: Are you sure you compile the file you are editing?
I held some tutorials at my university and most of the beginners made this mistake.
If you can definitely say you are compiling the file you are editing, then it could be caused by different new line settings but I consider this highly improbable.
Which editor/IDE do you use?
All you have to do is wait for the new C++0x standard. A newline is no longer required at the end of the source file. (And this took 40 years?)
Most Unix-based text editors will add a trailing newline automatically, but apparently
Notepad++ (which I've never used) doesn't.
The file doesn't need to end with a blank line (which would be represented as two newline
characters in a row), just a properly terminated one.
See if Notepad++ has a configuration option that tells it to automatically append a newline
when saving a file, or at least to ask whether you want to add one.
Great explanation - I had the same problem and solved it simply by using WordPad instead of Notepad :)
The problem has nothing to do with your C++ code; I can almost guarantee you that the uninitialized boolean in your program didn't cause the issue. It's a problem with the source file itself. A "Hello, world" program would have produced the same warning.
A text file, including a C++ source file, consists of lines of characters, where each line is terminated by an end-of-line marker. In Unix, and therefore in Cygwin (with the default settings), the end-of-line marker is a single '\n' (newline, linefeed) character. (Windows uses CR-LF pair ("\r\n").
It's possible for the very last line of a text file not to end with a newline character, but g++ prefers it to be terminated properly.
Most Unix-based text editors will add a trailing newline automatically, but apparently Notepad++ (which I've never used) doesn't.
The file doesn't need to end with a blank line (which would be represented as two newline characters in a row), just a properly terminated one.
See if Notepad++ has a configuration option that tells it to automatically append a newline when saving a file, or at least to ask whether you want to add one.
(The missing newline at the end of the file is probably what caused your problems pasting the code when you posted the question.)
Maybe it is some problem with some invisible character? I copy-paste your code and gets compiled without any warnings/errors, under Cygwin with the following g++:
$ g++ --version
g++ (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
It ended up that not initializing a boolean variable to false was the issue. However, I'm not sure whether it was actually the initialization that was the problem, or just the fact that the text editor might not actually save a file if you just append whitespace to the end of it. For those wondering, this was happening to me in Notepad++.