How do I print Unicode characters using ncurses in C++? - c++

I am making a chess game on the C++ console and I can't seem to be able to output the Unicode symbols for the chess pieces.
#define whiteking 0x2654
int main()
{
setlocale(LC_ALL, "");
initscr();
keypad(stdscr, TRUE);
wchar_t c = whiteking;
add_wch(c);
getch();
endwin();
return 0;
}
The error returned is:
In file included from main.cpp:4:0:
main.cpp: In function ‘int main()’:
main.cpp:624:5: error: invalid conversion from ‘wchar_t’ to ‘const cchar_t*’
[-fpermissive]
add_wch(c);
^
/usr/include/ncursesw/curses.h:1703:28: note: initializing argument 2 of
‘int wadd_wch(WINDOW*, const cchar_t*)’
extern NCURSES_EXPORT(int) wadd_wch (WINDOW *,const cchar_t *); /*
implemented */
The includes are:
#include <locale.h>
#include <ncursesw/ncurses.h>
#include <wchar.h>
#include <stdio.h>
None of the other stack overflow answers seems to help me. I am using this online compiler. Thank you for your help!

X/Open Curses (ncurses) uses a variety of datatypes. cchar_t is a structure, while wchar_t is not.
You can do what was intended using a different function:
#include <curses.h>
#include <locale.h>
#define whiteking 0x2654
int main()
{
setlocale(LC_ALL, "");
initscr();
keypad(stdscr, TRUE);
wchar_t s[2];
s[0] = whiteking;
s[1] = 0;
addwstr(s);
getch();
endwin();
return 0;
}

Related

Why can't I provide a string argument to printw in ncurses? [duplicate]

This question already has answers here:
How to convert a std::string to const char* or char*
(11 answers)
Closed 3 years ago.
For an application that I'm writing, I have a string type variable that I want to display within an ncurses window:
#include <iostream>
#include <ncurses.h>
#include <string>
int main(){
std::string mystring = "A sample string\n";
// Entering the ncurses window
initscr();
printw(mystring);
getch();
endwin();
}
which throws the following error at compilation:
test_app.cpp: In function ‘int main()’:
test_app.cpp:12:18: error: cannot convert ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘const char*’ for argument ‘1’ to ‘int printw(const char*, ...)’
printw(mystring);
Where am I going wrong? How can I rectify this?
Some key concepts in c++:
A string literal declaration (aka "this is a string literal") has a type const char[N], where N is the size of the string, including the null terminator.
std::string != const char[]
However, a std::string can be constructed with a const char[] using this constructor (found here):
basic_string( const CharT* s,
const Allocator& alloc = Allocator() );
Where CharT is your implementation specific char equivalent.
Now, notice how printw takes a const char*. You aren't passing a const char * to printw, you're passing a std::string, and they aren't implicitly convertible to a const char *.
We have two options to solve your problem...
1) Store the string as a char[] (aka char *):
#include <iostream>
#include <ncurses.h>
#include <string>
int main(){
char mystring[] = "A sample string\n"; // Can decay to a char * implicitly.
// Entering the ncurses window
initscr();
printw(mystring);
getch();
endwin();
}
2) Get a representation of the std::string as a char *:
#include <iostream>
#include <ncurses.h>
#include <string>
int main(){
std::string mystring = "A sample string\n";
// Entering the ncurses window
initscr();
// Since c++ 11, mystring.data() is required to return a null-terminated char *.
// If c++ version < c++11, use mystring.c_str().
printw(mystring.data());
getch();
endwin();
}

C++ Function error -- could not convert brace-enclosed initializer list to char*

New to C++, more familiar with MATLAB and Arduino. I'm trying to create (read: modify someone else's code) a C++ function to send a character array over serial--it's interacting with a C library (rs232.h). I keep getting this error when initializing the default value for the mode--bits/baud/parity array in the function initialization. Not sure if I am trying to do something that is not supported, if so, I can split up the variables. Thanks in advance for any help.
IDE: Code::Blocks
Compiler: MinGW-g++/GCC 7.3
Errors:
error: could not convert '{'8', 'N', '1', 0}' from '<brace-enclosed initializer list>' to 'char*'
Code:
#include <stdlib.h>
#include <stdio.h>
#include <Windows.h>
#include "rs232.h"
#include <string> /* Probably unnecessary */
bool Write(char (&toWrite)[256], int portNum=3, int bdrate=9600, char mode[]={'8','N','1','\0'})
{
int i, cport_nr = portNum - 1;
if(RS232_OpenComport(cport_nr, bdrate, mode))
{
return false;
}
while(1)
{
RS232_cputs(cport_nr, toWrite);
printf("sent: %s\n", toWrite);
Sleep(1000);
i++;
i %= 2;
}
return true;
}
Put the default value at a separate line:
bool Write(char (&toWrite)[256], int portNum=3, int bdrate=9600, char *mode=NULL) {
char mode_default[] = {'8','N','1','\0'};
if (mode == NULL) mode = mode_default;
Reason:
You cannot use default values with C array parameters (which really decay to pointers here) – UnholySheep

How to call a script from inside CPP code in linux

I am new to C++ coding using linux.Hence, my apologies if my question is trivial.
I need some help regarding calling some script/executable from inside a cpp file.
I downloaded few libraries (Blas, Lapack, libtsnnls-2.3.3). Configured and made executable. This executable was created when I configured and compiled libtsnnls-2.3.3.
I can call from command line:
cd /home/dkumar/libtsnnls-2.3.3/tsnnls
./genb_test
Now, I want to call the same command from a cpp file. It's something similar to "HelloWorld.cpp"
My Attempt (modified based on suggestion of #Biffer #timrau:
// 'Hello World!' program
#include <stdio.h> /* defines FILENAME_MAX */
#include <cstdlib> /* MODIFIED std::system */
#include <iostream>
#ifdef _MSC_VER
#include "direct.h"
#define GetCurrentDir _getcwd // window ??
#else
#include "unistd.h"
#define GetCurrentDir getcwd
#endif
int main()
{
std::cout << "Hello World!" << std::endl;
// const char *ParentFolder = "/home/dkumar/All_Matlab_Codes_DKU";
const char *ParentFolder = "/home/dkumar/libtsnnls-2.3.3/tsnnls/";
int res3 = chdir(ParentFolder);
// exceuting the command('./genb_test')
std::system('./genb_test');
return 0;
}
I get the following errors:
HelloWorld.cpp:36:10: warning: character constant too long for its type [enabled by default]
system('./genb_test');
^
HelloWorld.cpp: In function ‘int main()’:
HelloWorld.cpp:36:23: error: invalid conversion from ‘int’ to ‘const char*’ [-fpermissive]
system('./genb_test');
^
In file included from /usr/include/c++/4.8/cstdlib:72:0,
from HelloWorld.cpp:4:
/usr/include/stdlib.h:717:12: error: initializing argument 1 of ‘int system(const char*)’ [-fpermissive]
extern int system (const char *__command) __wur;
In c++ ' is used for characters ('a') and " is used for strings ("aaaa").
If you edit system('./genb_test') to be system("./genb_test") it might work.
You have single ' when calling your script. You want double "
#include <cstdlib> /* MODIFIED std::system */
int main()
{
// executing the command("./genb_test")
std::system("./genb_test");
return 0;
}
there is a function named system which could start a shell process to run your script, to do this, you need first include cstdlib header and then call the system function in your code
example
#include <cstdlib>
int main()
{
system("./myscript.sh");
}
The function system need a parameter of type std::string or a C-style string, so you will need the double quotation mark

Converting 'const char*' to 'LPCTSTR' for CreateDirectory

#include "stdafx.h"
#include <string>
#include <windows.h>
using namespace std;
int main()
{
string FilePath = "C:\\Documents and Settings\\whatever";
CreateDirectory(FilePath, NULL);
return 0;
}
Error: error C2664: 'CreateDirectory' : cannot convert parameter 1 from 'const char *' to 'LPCTSTR'
How do I make this conversion?
The next step is to set today's date as a string or char and concatenate it with the filepath. Will this change how I do step 1?
I am terrible at data types and conversions, is there a good explanation for 5 year olds out there?
std::string is a class that holds char-based data. To pass a std::string data to API functions, you have to use its c_str() method to get a char* pointer to the string's actual data.
CreateDirectory() takes a TCHAR* as input. If UNICODE is defined, TCHAR maps to wchar_t, otherwise it maps to char instead. If you need to stick with std::string but do not want to make your code UNICODE-aware, then use CreateDirectoryA() instead, eg:
#include "stdafx.h"
#include <string>
#include <windows.h>
int main()
{
std::string FilePath = "C:\\Documents and Settings\\whatever";
CreateDirectoryA(FilePath.c_str(), NULL);
return 0;
}
To make this code TCHAR-aware, you can do this instead:
#include "stdafx.h"
#include <string>
#include <windows.h>
int main()
{
std::basic_string<TCHAR> FilePath = TEXT("C:\\Documents and Settings\\whatever");
CreateDirectory(FilePath.c_str(), NULL);
return 0;
}
However, Ansi-based OS versions are long dead, everything is Unicode nowadays. TCHAR should not be used in new code anymore:
#include "stdafx.h"
#include <string>
#include <windows.h>
int main()
{
std::wstring FilePath = L"C:\\Documents and Settings\\whatever";
CreateDirectoryW(FilePath.c_str(), NULL);
return 0;
}
If you're not building a Unicode executable, calling c_str() on the std::string will result in a const char* (aka non-Unicode LPCTSTR) that you can pass into CreateDirectory().
The code would look like this:
CreateDirectory(FilePath.c_str(), NULL):
Please note that this will result in a compile error if you're trying to build a Unicode executable.
If you have to append to FilePath I would recommend that you either continue to use std::string or use Microsoft's CString to do the string manipulation as that's less painful that doing it the C way and juggling raw char*. Personally I would use std::string unless you are already in an MFC application that uses CString.

C++ stat.h incomplete type and cannot be defined

I am having a very strange issue with stat.h
At the top of my code, I have declarations:
#include <sys\types.h>
#include <sys\stat.h>
And function prototype:
int FileSize(string szFileName);
Finally, the function itself is defined as follows:
int FileSize(string szFileName)
{
struct stat fileStat;
int err = stat( szFileName.c_str(), &fileStat );
if (0 != err) return 0;
return fileStat.st_size;
}
When I attempt to compile this code, I get the error:
divide.cpp: In function 'int FileSize(std::string)':
divide.cpp:216: error: aggregate 'stat fileStat' has incomplete type and cannot be defined
divide.cpp:217: error: invalid use of incomplete type 'struct stat'
divide.cpp:216: error: forward declaration of 'struct stat'
From this thread: How can I get a file's size in C?
I think this code should work and I cannot figure out why it does not compile. Can anybody spot what I am doing wrong?
Are your \'s supposed to be /'s or am I just confused about your environment?
UNIX MAN page:
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int stat(const char *restrict path, struct stat *restrict buf);
If you're on Windows (which I'm guessing you might be because of the \'s), then I can't help because I didn't even know that had stat.