C++: Backspace characters not showing in stdout? - c++

I am implementing a shell that has command history. When the user presses the up or down arrow, the text in the current line is replaced with the previous or next command.
The algorithm I'm planning on implementing is fairly simple. If the current command has k characters, I output k '\b' characters to delete the k characters int he current line and then output the selected command to the line.
However, I'm trying to start out with something basic, such as seeing if outputting '\b' characters even works in deleting characters from the current stdout line:
#include <iostream>
#include <queue>
#include <deque>
#include <string>
using namespace std;
int main(int argc, char *argv[]){
cout << "asdf";
cout << "\b\b" << endl;
return 0;
}
The output of the above piece of code is:
asdf
When I expect:
as
Important: I want to delete characters after they are outputted to stdout.

You need ANSI escape codes. Try:
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[]){
cout << "asdf";
cout<<"\b\b\b\b\033[J";
return 0;
}
\033 stands for ESC and [J is a parameter to the code. ESC[J clears the screen from the cursor to the end of the screen. For more information: https://en.wikipedia.org/wiki/ANSI_escape_code#Fe_Escape_sequences
As #n. 1.8e9-where's-my-share m. mentioned, \b simply moves the cursor back one space, and does not rewrite anything, for most implementations.

I recommend to use ncurses and readline libraries.
Example:
sudo apt-get install libncurses5-dev libncursesw5-dev libreadline-dev
git clone https://github.com/ulfalizer/readline-and-ncurses
cd readline-and-ncurses
make
rlncurses
My environment:
lsb_release -d ; uname -r ; g++ --version | head -1
Description: Ubuntu 20.04.3 LTS
4.4.0-19041-Microsoft
g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0

Related

Script for running c++ inside Notepad++ without extra white line

I have a C++ script as follows:
NPP_SAVE
cd $(CURRENT_DIRECTORY)
g++ -o "$(NAME_PART).exe" "$(FULL_CURRENT_PATH)"
"$(NAME_PART).exe"
I try to compile my first C++ programming, print Hello, World.
#include <iostream>
using namespace std;
int main() {
cout << "Hello, World!";
return 0;
}
However, I see a an extra white line
Question:
How to delete it?
It means as following:

carriage return causing cout to overwrite characters and printing out of order

This is a question I copied from another question that got put on hold. I am wondering why the extra hyphen is being added to the beginning of the output buffer stream when I concatenate more than one string in cout, and why it is overwriting a character there?
Below is a minimal example showing how printing any string causes this to happen. I posted this question before but it was put on hold due to lack of reproducibility. The reason it wasn't reproducible is because when I copied the text file I wasn't copying hidden characters. It turns out when I did cat -e ex.txt, the lines were all ending with ^M for some reason. This is the cause of the problem. answering it below.
-Paul
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
int main(int argc, char* argv[]){
ifstream infile(argv[1]);
string str;
getline(infile, str);
cout<<"str: "<<str<<"-"<<endl;
}
I compile and run the code with:
g++ -o hw4.exe prog4.cpp
./hw4.exe ex2.txt
$ cat -e ex2.txt
Bella Abzug ^M$
And below is the output of
od -x ex2.txt
0000000 6542 6c6c 2061 6241 757a 2067 0a0d
0000016
The output:
-tr: Bella Abzug
But I still do not know WHY this is the case. Why would a carriage return followed by a line ending cause this behavior?
https://en.wikipedia.org/wiki/Control_character
^M is carriage return, ie 'move cursor to start of line'

How can I enter continuously by another C++ program in C system / popen command?

I want to build a compile system in an online judge system.
Environment: Ubuntu 12.04 LTS, g++ version 4.9
My workflow is "Compile cpp" -> "Execute it" -> "Record message".
But I got some problems when "the cpp file exist 'scanf' or 'cin' commands".
Because this is a auto-compile & run program, there is an other input need to load. (Is a string from function call not enter in terminal by myself)
My problem
How can I run the executeCommand (below code in compiler.cpp), using the string input (below too) to enter for this program. If the executed program exist any scanf, cin or other commands.
compiler.cpp
This is system command version, can replace to popen command too.
#include <string>
#include <cstdlib>
#include <fstream>
#include <iostream>
using namespace std;
int main(int argc, char ** argv) {
// Compiler one cpp file.
string compileCommand = "(g++ --std=c++11 ./main.cpp -o ./main.out) 2> main.err";
system(compileCommand.c_str());
// Execute this program.
string executeCommand = "(time timeout -k1s 0.01s ./main.out) > result.txt 2> time.txt";
system(executeCommand.c_str());
// I want the above main.out will scanf from this string.
string input = "Hello world, this is first line.\nThis is second line.";
return 0;
}
main.cpp
#include <stdlib.h>
#include <stdio.h>
int main () {
char str[256];
scanf("%s", str);
printf("%s\n", str);
return 0;
}
You probably need popen(3) (and you flagged your question as such).
FILE*pcmd = popen("time ./main.out", "w");
if (!pcmd) { perror("popen"); exit(EXIT_FAILURE); };
fprintf(pcmd, "Hello world, this is first line.\n");
fprintf(pcmd, "This is the second line.\n");
fflush(pcmd);
int bad = pclose(pcmd);
if (bad) {fprintf(stderr, "pclose failed %d\n", bad); };
Be aware of code injection issues, in particular when passing a computed command to popen or system
You might need some event loop around poll(2). Then use fork, execve, pipe and other syscalls(2) explicitly, so read Advanced Linux Programming
All you need is a pipe, system( "echo YOUR_STRING | ./main.out " )

Xcode reading chars from file in c++

I have the following code to read a character from a file:
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, const char * argv[])
{
ifstream f("text.txt");
char c;
f.get(c);
cout << c << endl;
return 0;
}
and my text.txt file contains:
hello world!
However, when I run this on Xcode, I get an inverted question mark as the output.
It works fine on terminal, but not on Xcode. Does anyone know why this happens?
I'm using Xcode to debug some code, but I cant do that anymore because this problem is causing a lot of other errors in my program.
Your text.txt file will not be at the executable path.
Go to your Build Phases - > Copy Files -> Add Your text file
Make sure that:
Destination should be Products Directory
Copy only when installing should be unchecked

How can I print (☞゚ヮ゚)☞ with Ncurses?

I would like to print (☞゚ヮ゚)☞ with the Ncurses library using C++ in Ubuntu.
First of all, you can do this by simply having:
std::cout << "(☞゚ヮ゚)☞" << std::endl;
And it works just fine.
However, when printing using Ncurses, I think that you need to use printw(char[]). In which case, I try something like this:
std::string str = "(☞゚ヮ゚)☞"; // String
initscr(); // Start curses mode
printw(str.c_str()); // Print
getch(); // Wait for input
endwin(); // Exit curses mode
But it outputs:
(�~X~^��~�~C���~)�~X~^
I had thought that maybe it was c_str()'s fault, but when I do it with std::cout it works just fine too.
How can I print that text with Ncurses? Why does it work with std::cout and not with Ncurses' printw(char[])?
I compile using
g++ Main.cpp -lncurses
In a 64-bit machine. Ubuntu (64 bits too) is running in VirtualBox with OSX as host.
Update:
I've been redirected to https://stackoverflow.com/a/9927113/555690. The solution there doesn't seem to fix my problem - instead, this is how it looks now:
(M-b~X~^M-oM->~M-c~CM-.M-oM->~)M-b~X~^
I guess I'll post this as the answer. So, Ubuntu does apparently not by default ship with the Unicode supporting version. So you first need to install it with
sudo apt-get install libncursesw5-dev
then you can compile this
#include <iostream>
#include <string>
#include "locale.h"
#include "ncursesw/ncurses.h"
using namespace std;
int main()
{
setlocale(LC_ALL, "");
std::string str = "(☞゚ヮ゚)☞"; // String
initscr(); // Start curses mode
printw(str.c_str()); // Print
getch(); // Wait for input
endwin();
return 0;
}
and it'll work without a hitch.
Mind the #include "ncursesw/ncurses.h"