This question already has answers here:
Why does a % percentage appear at the end of the output to standard out but not when I use endl? [duplicate]
(2 answers)
Closed 20 days ago.
I am executing some simple C++ code in VSCode on a MAC + code runner.
There are no warnings or compile errors, but in the terminal output window there is this annoying '%' symbol appended, as you can see below:
What causes it, and how can i get rid of it?
The inverse+bold % indicates a lack of '\n' at the end of the line. zsh has this to let you see unterminated lines in a command's output. You can get rid of it by using std::endl like so:
std::cout<< z << std::endl;
// or
std::cout<< z << '\n';
Keep in mind that std::endl flushes the output buffer and '\n' doesn't.
From zsh doc:
PROMPT_SP <D>
Attempt to preserve a partial line (i.e. a line that did not end with a newline) that would otherwise be covered up by the command prompt due to the PROMPT_CR option. This works by outputting some cursor-control characters, including a series of spaces, that should make the terminal wrap to the next line when a partial line is present (note that this is only successful if your terminal has automatic margins, which is typical).
When a partial line is preserved, by default you will see an inverse+bold character at the end of the partial line: a % for a normal user or a # for root. If set, the shell parameter PROMPT_EOL_MARK can be used to customize how the end of partial lines are shown.
NOTE: if the PROMPT_CR option is not set, enabling this option will have no effect. This option is on by default.
Related
I have a simple C++ program that lists the arguments it gets:
#include <iostream>
int main(int argc, char* argv[]) {
for (int i = 1; i < argc; i++) {
std::cout << argv[i] << std::endl;
}
return 0;
}
I'm just testing/figuring this out but the ultimate intention is for this to accept the names of some files and directories.
So I pass it these arguments:
"\\server\directory\file.ext" "C:\trailing\backslash\" "file.txt"
But this is what's printed:
\\server\directory\file.ext
C:\trailing\backslash" file.txt
i.e. the trailing slash on the second argument makes it think the closing quote is escaped.
I'm setting the arguments in the property pages of VS2017, but I get the same output when:
I call the exe from PowerShell.
I allow an external tool to pass my
exe arguments that it has built (which will be how this is ultimately
used).
How can I get my program to understand that the quoted path with a trailing slash is one argument?
EDIT
Section 4 of this article describes exactly my problem. Basically I want to make my C++ program interpret arguments in the same way that a batch file or VBScript does. I cannot change how the arguments come in to my program
EDIT I will simplify the question:
The C++ program above behaves like this:
I want it to behave like this:
What do I have to do to the program or compiler in order for that to happen?
You have to protect the trailing backslash with another backslash, otherwise the backslash is treated as an escape character for the following double quote.
See this blog post by Raymond Chen for a rationale for this behavior.
Here is a quote of the relevant part:
A string of backslashes not followed by a quotation mark has no special meaning.
An even number of backslashes followed by a quotation mark is treated as pairs of protected backslashes, followed by a word terminator.
An odd number of backslashes followed by a quotation mark is treated as pairs of protected backslashes, followed by a protected quotation mark.
I tried compiling this with an extra slash to the second argument like below and was able to produce the desired output !
"\\server\directory\file.ext" "C:\trailing\backslash\\" "file.txt"
This was the output
/home/a.out
\server\directory\file.ext
C:\trailing\backslash\
file.txt
Upvote my post if it helps you :D
If you are not happy with the command line parsing you can do it by your own:
Just use GetCommandLine and parse your command line as you want it.
Other post already described how the command line is/should be treated (see blog post of Raymond Chen).
I am trying to run a C++ application where I am passing some command line arguments to it as follows:
./startServer -ip 10.78.242.4 tcpip{ldap=no;port=2435}
The application is getting crashed because it is not able to get the correct port. Searching over the web, I found that ";" is treated an end of command character (Semicolon on command line in linux) so everything after that is getting ignored. I also understand the putting it inside the quotes will work fine. However, I do not want to force this restriction of putting the arguments in the quotes on the users. So, I want to know is there a way I can process the ";" character with the argv array?
The semicolon separates two commands so your command line is equivalent to
./startServer -ip 10.78.242.4 tcpip{ldap=no
port=2435}
Your application will never know anything about either the semi colon or the second command, these will be completely handled by the shell. You need to escape the colon with a back slash or enclose it in quotes. Other characters which may cause similar issues include: $,\-#`'":*?()&|
Complex strings are much easier to pass either from a file or through stdin.
You need to quote not only the ; but in the general case also the { and }:
./startServer -ip 10.78.242.4 'tcpip{ldap=no;port=2435}'
If your users are required to type in that complicated last argument, then they can also be made to quote it.
I was trying to test my classes when I encountered a weird problem in the input of test cases.
I tried to simplify the input to see what went wrong so I created the program below.
#include <iostream>
#include <string>
int main()
{
std::string number;
while (std::getline(std::cin, number))
{
std::cout << std::string(number) << " ";
}
}
Basically, I am getting each line of text and storing it in a string variable using getline(). Then I display each string using std::cout and append a single space character.
My input file contains this:
one six
one seven
The expected output should be like this:
one six one seven
But instead, I get this:
one seven
That is a space character followed by the second line of the input. It disregards the first line of input. I know for a fact that each line are being read properly because they were correctly displayed when I replaced the code with this:
std::cout << std::string(number) << std::endl;
This error is quite new to me. What's happening here? Can anybody explain? TIA!
Ok, its clear.
Your input file must be : one six\r\ntwo seven\r\n with normal Windows EOL.
When you read it under cygwin, you get in first read one six\r, only the \n being eaten by getline, and same one seven\r on the second line.
So you write : one six\r one seven\r (with an ending blank). But the \r alone put the curson back in first column of same line and second line erases first.
And normally the problem is not visible if you replace the ending blank by a std::eol that puts the cursor on a new line. The tab (\t) if really a special case : it put the cursor on eighth column exactly where you expect it, but by pure chance. If you invert the two lines it would be more apparent because you would see the remaining of first line at end of second.
You can confirm it by writing the output to a file and editing it.
I could reproduce it under Linux with a Windows EOL. The reason for that is that Cygwin closely mimics Unix-Linux and use Unix EOL convention of only \n.
I'm writing a little program in C++, and come across a strange error:
src/Makefile/Tool.cpp:42:3: error: stray ‘\302’ in program
src/Makefile/Tool.cpp:42:3: error: stray ‘\240’ in program
I'm writing this program in Vim and the corresponding line (showing hidden characters) is:
>--->---std::vector<std::string> { "--debug" }$
This question is not about resolving this error, as I just have to copy back the line and the error-cause disappear.
It seems that the error is caused by some characters even hidden by Vim after activating all relative options!
The question is about what could have caused those errors.
"\302\240" is UTF-8 for U+00A0 NO-BREAK SPACE. Vim won’t normally highlight it as anything special, so it’s possible for one to sneak in even if you have 'list' mode enabled.
You can highlight them with:
:set listchars+=nbsp:.
or any character you like.
As aforementioned, it is due to some not visible characters in your source.
One great solution for this is to edit your file in octal mode and you will be able "to see" these characters:
od -c MyClass.hpp
Then you can see the "strangers" in the octal flow:
0001240 t s t r i n g & n a m e )
0001260 { **302 240** t h i s - > n a m e =
0001300 n a m e ; } \n \n \n \t \t \t \t /
These two characters in bold are the cause of messages like:
error: stray ‘\302’ in program
You can then remove them, and rebuild.
For me this problem came from copying my code over from a web browser.
I tried doing a :%s/ / /g in Vim to replace all spaces with real spaces, but this has failed.
I deleted the leading white space of all lines reporting this error and inserted the space characters again. This is labour intensive, but appears to be the only solution I could find.
I had the same issue and it was the character encoding for the spaces before each line. This happened due to copying from notes programs that was synced up with Exchange Server and iCloud. All I needed to do is apply and replace all using Notepad to all the strange spaces with normal ones and everything compiled normally again.
Okay, I have been researching on how to do this, but say I am running a program that has a whole bit of output on the terminal, how would I clear the screen from within my program so that I can keep my program running?
I know I can just type clear in terminal and it clears it fine, but like I said, for this program it would be more beneficial for me.
I found something that works, however, I'm not sure what it is or what it is doing.
cout << "\033[2J\033[1;1H";
That works but I have no clue what it is, if you could explain it, than I would much appreciate it.
These are ANSI escape codes. The first one (\033[2J) clears the entire screen (J) from top to bottom (2). The second code (\033[1;1H) positions the cursor at row 1, column 1.
All ANSI escapes begin with the sequence ESC[, have zero or more parameters delimited by ;, and end with a command letter (J and H in your case). \033 is the C-style octal sequence for the escape character.
See here for the full roadshow.
Instead of depending on specific escape sequences that may break in unexpected situations (though accepting that trade-off is fine, if it's what you want), you can just do the same thing you'd do at your shell:
std::system("clear");
Though generally system() is to be avoided, for a user-interactive program neither the extra shell parsing nor process overhead is significant. There's no problem with shell escaping either, in this case.
You could always fork/exec to call clear if you did want to avoid system(). If you're already using [n]curses or another terminal library, use that.
For portability you should get the string from termcap's cl (clear) capability (Clear screen and cursor home). (Or use std::system("clear") as told by Roger Pate).
man 3 termcap (in ncurses)
man 5 termcap
set | grep TERMCAP
you can write in a terminal "clear > data" and read in data the escapes sequance
0x1B[H0x1B[2J0x1B[3J
so
std::cout << "\033[H\033[2J\033[3J" ;