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

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"

Related

What can I replace with the sleep command in the Windows variant of ncurses?

#include <curses.h>
#include <unistd.h>
#include <iostream>
int main() {
initscr();
mvaddstr(10, 10, "Hello, world");
refresh();
sleep(4);
endwin();
std::cout << "DONE\n";
}
I'm working on a project and I need to take down the curses windows for a while just to write a path to directory in cmd and then let the curses windows come back. I found this code on this site and tried to use sleep command in the code but it didn't work.
So if anyone knew how to solve this please write it down here. Thnx :)
napms is the (portable) curses function to use instead of sleep

Reading a file that contains chinese characters (C++)

I got issues reading a file that contains chinese characters. I know that the encoding of the file is Big5.
Here is my example file (test.txt), I can't include it here because of the chinese characters: https://gist.github.com/haruka98/974ca2c034ebd8fe7eeac4124739fc41
This is my minimal code example (main.cpp), the one I'm actually using breaks down each line and does things with the different fields.
#include <string>
#include <fstream>
#include <iostream>
int main(int argc, char* argv[]) {
setlocale(LC_ALL, "Chinese-traditional");
std::wstring wstr;
std::wifstream input_file("test.txt");
std::wofstream output_file("test_output.txt");
int counter = 0;
while(std::getline(input_file, wstr)) {
for(int i = 0; i < wstr.size(); i++) {
if(wstr[i] == L'|') {
counter++;
}
}
output_file << wstr << std::endl;
}
input_file.close();
output_file.close();
std::cout << counter << std::endl;
return 0;
}
To compile my program:
g++ -o test main.cpp -std=c++17
On Windows 10 I got my expected output. I got the entire file copied to "test_output.txt" and the 129 output in the terminal.
On Linux (Debian 9) I got the terminal output 4 and the file "test_output.txt" only contains the first line and the "1|" from the second.
Here is what I tried:
My first guess was the CR LF and LF issue when using both Windows and Linux. But testing both CR LF and LF with the file did not help.
Then I thought that the "Chinese-traditional" might not work on Linux. I replaced it with "zh_TW.BIG5" but did not get the expected result either.
First check you have the locale for "Chinese-traditional" installed. On Linux this is zh_TW.UTF-8. You can check using locale -a. If it's not listed, install it:
sudo locale-gen zh_TW.UTF-8
sudo update-locale
(There's a list of locales here with their names on Linux and Windows.)
Then use imbue with the input and output streams to set the locale of the streams.
By default, std::wcout is synchronized to the underlying stdout C stream, which uses an ASCII mapping and displays ? in place of Unicode characters it cannot handle. If you want to print Unicode characters to the terminal, you have to turn that synchronization off. You can do that with one line and set the locale of the terminal:
std::ios_base::sync_with_stdio(false);
std::wcout.imbue(loc);
Amended version of your code:
#include <string>
#include <locale>
#include <fstream>
#include <iostream>
int main(int argc, char* argv[])
{
auto loc = std::locale("zh_TW.utf8");
//Disable synchronisation with stdio & set locale
std::ios::sync_with_stdio(false);
std::wcout.imbue(loc);
//Set locale of input stream
std::wstring wstr;
std::wifstream input_file("test.txt");
input_file.imbue(loc);
//Set locale of outputput stream
std::wofstream output_file("test_output.txt");
output_file.imbue(loc);
int counter = 0;
while(std::getline(input_file, wstr)) {
for(int i = 0; i < wstr.size(); i++) {
if(wstr[i] == L'|') {
counter++;
}
}
std::wcout << wstr << std::endl;
output_file << wstr << std::endl;
}
input_file.close();
output_file.close();
std::wcout << counter << std::endl;
return 0;
}
setlocale affects the locale of your program.
It has no effect on the default encoding of the text displayed by the terminal window. The terminal window is an independent application, with its own locale.
Pretty much all modern Linux distributions default to UTF-8 as the encoding for the system console and the terminal windows (gnome-terminal, Konsole, xfce4-terminal, etc...).
Changing your program's locale only affects how your application interprets text, but the terminal still expects your application to produce UTF-8 output. The terminal window has no knowledge of the internal locale of the application running in the terminal window. Terminal windows expect applications to produce output using the system locale's character encoding.
It is theoretically possible for the C library to know the default system encoding and silently transcode all the output, however it does not work this way.
You will have to do all the work of transcoding big5 to UTF-8, using the iconv library, on Linux.
A low cost, cheap shortcut, would be for your program to fork and run the iconv command line tool as a child process, and pipe its output to it, then let iconv do the transcoding on the fly.
use std::wcout to print std::wstring instead of std::cout :-)

How to build your own CMD using C++?

Recently I want to enhance CMD in Win10 by myself using C++. I don't want to change the original framework of it but to translate the command. At first i wrote something like this:
#include <unistd.h>
#include <iostream>
#include <string>
using namespace std;
int main()
{
string initial = "retr0# ";
string s;
while(1)
{
cout << initial;
getline(cin,s);
if(s!="exit")
{
system(s.c_str());
cout << "------" << endl;
}
else break;
}
system("pause");
return 0;
}
But I found that if you entered command like "E:" or something else to change the directory, it is impossible for the new thread to inherit the context. My question is, how to solve the problem like this?
In most operating systems (including 1970 era Unix), the working directory is specific to each process.
The system function will run another process. So even if you change its working directory, it only affects the process started by system, not the process running your program.
So you need to define a syntax (perhaps the same cd as Windows CMD has) and parse and implement that command in your own program. You could use SetCurrentDirectory or _chdir

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 " )

make sounds (beep) with c++

How to make the hardware beep sound with c++?
Print the special character ASCII BEL (code 7)
cout << '\a';
Source
If you're using Windows OS then there is a function called Beep()
#include <iostream>
#include <windows.h> // WinApi header
using namespace std;
int main()
{
Beep(523,500); // 523 hertz (C5) for 500 milliseconds
cin.get(); // wait
return 0;
}
Source: http://www.daniweb.com/forums/thread15252.html
For Linux based OS there is:
echo -e "\007" >/dev/tty10
And if you do not wish to use Beep() in windows you can do:
echo "^G"
Source: http://www.frank-buss.de/beep/index.html
There are a few OS-specific routines for beeping.
On a Unix-like OS, try the (n)curses beep() function. This is likely to be more portable than writing '\a' as others have suggested, although for most terminal emulators that will probably work.
In some *BSDs there is a PC speaker device. Reading the driver source, the SPKRTONE ioctl seems to correspond to the raw hardware interface, but there also seems to be a high-level language built around write()-ing strings to the driver, described in the manpage.
It looks like Linux has a similar driver (see this article for example; there is also some example code on this page if you scroll down a bit.).
In Windows there is a function called Beep().
alternatively in c or c++ after including stdio.h
char d=(char)(7);
printf("%c\n",d);
(char)7 is called the bell character.
You could use conditional compilation:
#ifdef WINDOWS
#include <Windows.h>
void beep() {
Beep(440, 1000);
}
#elif LINUX
#include <stdio.h>
void beep() {
system("echo -e "\007" >/dev/tty10");
}
#else
#include <stdio.h>
void beep() {
cout << "\a" << flush;
}
#endif
std::cout << '\7';
Here's one way:
cout << '\a';
From C++ Character Constants:
Alert: \a
#include<iostream>
#include<conio.h>
#include<windows.h>
using namespace std;
int main()
{
Beep(1568, 200);
Beep(1568, 200);
Beep(1568, 200);
Beep(1245, 1000);
Beep(1397, 200);
Beep(1397, 200);
Beep(1397, 200);
Beep(1175, 1000);
cout<<endl;
_getch()
return 0
}
I tried most things here, none worked on my Ubuntu VM.
Here is a quick hack (credits goes here):
#include <iostream>
int main() {
system("(speaker-test -t sine -f 1000)& pid=$!; sleep 1.0s; kill -9 $pid");
}
It will basically use system's speaker-test to produce the sound. This will not terminate quickly though, so the command runs it in background (the & part), then captures its process id (the pid=$1 part), sleeps for a certain amount that you can change (the sleep 1.0s part) and then it kills that process (the kill -9 $pid part).
sine is the sound produced. You can change it to pink or to a wav file.
Easiest way is probbaly just to print a ^G ascii bell
The ASCII bell character might be what you are looking for. Number 7 in this table.
cout << "\a";
In Xcode, After compiling, you have to run the executable by hand to hear the beep.