How might one go about printing an em dash in C?
One of these: —
Whenever I do: printf("—") I just get a ù in the terminal.
Thank you.
EDIT: The following code is supposed to print out an Xs an Os looking grid with em dashes for the horizontal lines.
int main ()
{
char grid[3][3] = {{'a', 'a', 'a'}, {'a', 'a', 'a'}, {'a', 'a', 'a'}};
int i, j;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
if (j != 0)
{
printf("|");
}
printf(" %c ", grid[i][j]);
}
if (i != 2)
{
printf("\n——————————————\n");
}
}
return 0;
}
Output: (The "ù"s should be "—"s)
a | a | a
ùùùùùùùùùùùù
a | a | a
ùùùùùùùùùùùù
a | a | a
EDIT: I'm on Windows 10 x64 using Codeblocks 16.01 with C11.
EDIT: I was informed of box characters and the question has morphed into how to print those, hence the title and tag change.
In standard C, you use wide characters and wide strings:
#include <stdlib.h>
#include <locale.h>
#include <stdio.h>
#include <wchar.h>
int main(void)
{
setlocale(LC_ALL, "");
fwide(stdout, 1);
wprintf(L"🞨🞩🞪🞫🞬🞭🞮 🞉🞈🞇🞆🞅\n");
wprintf(L" │ │ \n");
wprintf(L"───┼───┼───\n");
wprintf(L" │ │ \n");
wprintf(L"───┼───┼───\n");
wprintf(L" │ │ \n");
return EXIT_SUCCESS;
}
You can use wide character constants like L'┼'; their conversion specifier for printf() and wprintf() functions is %lc. Similarly, a wide string constant has an L prefix, and its conversion specifier is %ls.
Unfortunately, you are limited to the mangled version of C Microsoft provides, so it may or may not work for you.
The above code does not work in Windows, because Microsoft does not want it to. See Microsoft documentation on setlocale() for details:
The set of available locale names, languages, country/region codes, and code pages includes all those supported by the Windows NLS API except code pages that require more than two bytes per character, such as UTF-7 and UTF-8.
In other words, Microsoft's C localization is limited to one-byte code pages, and specifically excludes any Unicode locales. This is, however, purely part of Microsoft's EEE strategy to bind you, a budding developer, to Microsoft's own walled garden, so that you will not write actual portable C code (or, horror of horrors, avail yourself to POSIX C), but are mentally locked to the Microsoft model. You see, you can use _setmode() to enable Unicode output.
As I do not use Windows at all myself, I cannot verify whether the following Windows-specific workarounds actually work or not, but it is worth trying. (Do report your findings in a comment, Windows users, please, so I can fix/include this part of this answer.)
#include <stdlib.h>
#include <locale.h>
#include <stdio.h>
#include <wchar.h>
#ifdef _WIN32
#include <io.h>
#include <fcntl.h>
static int set_wide_stream(FILE *stream)
{
return _setmode(_fileno(stream), _O_U16TEXT);
}
#else
static int set_wide_stream(FILE *stream)
{
return fwide(stream, 1);
}
#endif
int main(void)
{
setlocale(LC_ALL, "");
/* After this call, you must use wprintf(),
fwprintf(), fputws(), putwc(), fputwc()
-- i.e. only wide print/scan functions
with this stream.
You can print a narrow string using e.g.
wprintf(L"%s\n", "Hello, world!");
*/
set_wide_stream(stdout, 1);
/* These may not work in Windows, because
the code points are 0x1F785 .. 0x1F7AE
and Windows is probably limited to
Unicode 0x0000 .. 0xFFFF */
wprintf(L"🞨🞩🞪🞫🞬🞭🞮 🞉🞈🞇🞆🞅\n");
/* These are from the Box Drawing Unicode block,
U+2500 ─, U+2502 │, and U+253C ┼,
and should work everywhere. */
wprintf(L" │ │ \n");
wprintf(L"───┼───┼───\n");
wprintf(L" │ │ \n");
wprintf(L"───┼───┼───\n");
wprintf(L" │ │ \n");
return EXIT_SUCCESS;
}
Related
In a C program in Windows 10, I should print the word TYCHÊ on the screen, but I cannot print the letter Ê (Hex code: \xCA):
#include <stdlib.h>
#include <stdio.h>
char *Word;
int main(int argc, char* argv[]){
Word = "TYCH\xCA";
printf("%s", Word);
}
What's wrong?
Windows is a pain when it comes to printing Unicode text, but the following should work with all modern compilers (MSVC 19 or later, g++ 9 or greater) on all modern Windows systems (Windows 10 or greater), in both Windows Console and Windows Terminal:
#include <iostream>
#include <windows.h>
int main()
{
SetConsoleOutputCP( CP_UTF8 );
std::cout << "TYCHÊ" << "\n";
}
Make sure your compiler takes UTF-8 as the input character set. For MSVC 19 you need a flag. I think it is the default for later versions, but I am unsure on that point:
cl /EHsc /W4 /Ox /std:c++17 /utf-8 example.cpp
g++ -Wall -Wextra -pedantic-errors -O3 -std=c++17 example.cpp
EDIT: Dangit, I misread the language tag again. :-(
Here’s some C:
#include <stdio.h>
#include <windows.h>
int main()
{
SetConsoleOutputCP( CP_UTF8 );
printf( "%s\n", "TYCHÊ" );
return 0;
}
You can try with this line
printf("%s%c", Word, 0x2580 + 82);
this can print your Ê.
I used CLion for resolve it, on another IDE it may not give the same result.
In the Windows Command Line you should choose the Code Page 65001:
CHCP 65001
If you want to silently do that directly from the source code:
system("CHCP 65001 > NUL");
In the C source code you should use the <locale.h> standard header.
#include <locale.h>
At the beginning of your program execution you can write:
setlocale(LC_ALL, "");
The empty string "" initializes to the default encoding of the underlying system (that you previously choose to be Unicode).
However, this answer of mine is just a patch, not a solution.
It will help you to print the french characters, at most.
Handling encoding in Windows command line is not straight.
See, for example: Command Line and UTF-8 issues
Why printf() can display é (\u00E9 int UTF-16) and putwchar() can't ?
And what is the right syntax to get putwchar displaying é correctly ?
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main() {
wint_t wc = L'\u00E9';
setlocale(LC_CTYPE, "fr_FR.utf8");
printf("%C\n", wc);
putwchar((wchar_t)wc);
putchar('\n');
return 0;
}
Environnement
OS : openSUSE Leap 42.1
compiler : gcc version 4.8.5 (SUSE Linux)
Terminal : Terminator
Terminal encoding : UTF-8
Shell : zsh
CPU : x86_64
Shell env :
env | grep LC && env | grep LANG
LC_CTYPE=fr_FR.utf8
LANG=fr_FR.UTF-8
GDM_LANG=fr_FR.utf8
Edit
in :
wint_t wc = L'\u00E9'
setlocale(LC_CTYPE, "");
out:
C3 A9 0A E9 0A
in:
wint_t wc = L'\xc3a9';
setlocale(LC_CTYPE, "");
out:
EC 8E A9 0A A9 0A
You cannot mix wide character and byte input/output functions (printf is a byte output function, regardless if it includes formats for wide characters) on the same stream. The orientation of a stream can only be reset with freopen, which must be done again before calling the byte-oriented putchar function.
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main() {
wint_t wc = L'\u00E9';
setlocale(LC_CTYPE, "");
printf("%lc\n", wc);
freopen(NULL, "w", stdout);
putwchar((wchar_t)wc);
freopen(NULL, "w", stdout);
putchar('\n');
return 0;
}
The fact that the orientation can only be set by reopening the stream indicates that this is not intended to be done trivially, and most programs should use only one kind of output. (i.e. either wprintf/putwchar, or printf/putchar, using printf or wctomb if you need to print a wide character)
The problem is your setlocale() call failed. If you check the result you'll see that.
if( !setlocale(LC_CTYPE, "fr_FR.utf8") ) {
printf("Failed to set locale\n");
return 1;
}
The problem is fr_FR.utf8 is not the correct name for the locale. Instead, use the LANG format: fr_FR.UTF-8.
if( !setlocale(LC_CTYPE, "fr_FR.UTF-8") ) {
printf("Failed to set locale\n");
return 1;
}
The locale names are whatever is installed on your system, probably in /usr/share/locale/. Or you can get a list with locale -a.
It's rare you want to hard code a locale. Usually you want to use whatever is specified by the environment. To do this, pass in "" as the locale and the program will figure it out.
if( !setlocale(LC_CTYPE, "") ) {
printf("Failed to set locale\n");
return 1;
}
How can I assign non-ASCII characters to a wide char and print it to the console? This code down doesn't work:
#include <stdio.h>
int main(void)
{
wchar_t wc = L'ć';
printf("%lc\n", wc);
printf("%ld\n", wc);
return 0;
}
Output:
263
Press [Enter] to close the terminal ...
I'm using MinGW GCC on Windows 7.
You should use wprintf to print wide-character strings:
wprintf(L"%c\n", wc);
I think your calls to printf() fail with an «Illegal byte sequence» error returned in errno, at least that is what happens here on MacOS X with the above example code (and also if using wprintf() instead of printf()). For me it works when I call setlocale(LC_ALL, ""); before the call to printf() so that it stops using the C locale by default:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
int main(void)
{
wchar_t wc = L'ć';
setlocale(LC_ALL, "");
printf("%lc\n", wc);
return 0;
}
It is unclear what platform/compiler you are on, so YMMV.
use wprintf("%lc\n" ,wc); and you will get your desired output
#include <stdio.h>
#include <stdlib.h>
#include <uuid/uuid.h>
int main(void) {
puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */
uuid_t uuid;
int uuid_generate_time_safe(uuid);
printf("%x",uuid);
return EXIT_SUCCESS;
}
I just wonder why uuid is not 16 bytes long?
I use DEBUG to view the memory, It is indeed not 16 bytes.
And I use libpcap to develop my program, The uuid is not unique.
I just tried your program on my system, and uuid is 16 bytes long. But your program doesn't display its size.
The line:
int uuid_generate_time_safe(uuid);
isn't a call to the uuid_generate_time_safe function, it's a declaration of that function with uuid as the (ignored) name of the single parameter. (And that kind of function declaration isn't even valid as of the 1999 standard, which dropped the old "implicit int" rule.)
Your printf call:
printf("%x",uuid);
has undefined behavior; "%x" requires an argument of type unsigned int.
If you look in /usr/include/uuid/uuid.h, you'll see that the definition of uuid_t is:
typedef unsigned char uuid_t[16];
The correct declaration of uuid_generate_time_safe (see man uuid_generate_time_safe) is:
int uuid_generate_time_safe(uuid_t out);
You don't need that declaration in your own code; it's provided by the #include <uuid/uuid.h>.
Because uuid_t is an array type, the parameter is really of type unsigned char*, which is why the function is seemingly able to modify its argument.
Here's a more correct program that illustrates the use of the function:
#include <stdio.h>
#include <uuid/uuid.h>
int main(void) {
uuid_t uuid;
int result = uuid_generate_time_safe(uuid);
printf("sizeof uuid = %d\n", (int)sizeof uuid);
// or: printf("sizeof uuid = %zu\n", sizeof uuid);
if (result == 0) {
puts("uuid generated safely");
}
else {
puts("uuid not generated safely");
}
for (size_t i = 0; i < sizeof uuid; i ++) {
printf("%02x ", uuid[i]);
}
putchar('\n');
return 0;
}
On my system, I got the following output:
sizeof uuid = 16
uuid not generated safely
26 9b fc b8 89 35 11 e1 96 30 00 13 20 db 0a c4
See the man page for information about why the "uuid not generated safely" message might appear.
Note that I had to install the uuid-dev package to be able to build and run this program.
I'm writting a program in C and I want to have Greek characters in the menu when I run it in cmd.exe . Someone said that in order to include Greek characters you have to use a printf that goes something like this:
printf(charset:IS0-1089:uffe);
but they weren't sure.
Does anyone know how to do that?
Assuming Windows, you can:
set your console font to a Unicode TrueType font:
emit the data using an "ANSI" mechanism
This code prints γειά σου:
#include "windows.h"
int main() {
SetConsoleOutputCP(1253); //"ANSI" Greek
printf("\xE3\xE5\xE9\xDC \xF3\xEF\xF5");
return 0;
}
The hex codes represent γειά σου when encoded as windows-1253. If you use an editor that saves data as windows-1253, you can use literals instead. An alternative would be to use either OEM 737 (that really is a DOS encoding) or use Unicode.
I used SetConsoleOutputCP to set the console code page, but you could type the command chcp 1253 prior to running the program instead.
you can print a unicode char characters by using printf like this :
printf("\u0220\n");
this will print Ƞ
I think this might only work if your console supports Greek. Probably what you want to do is to map characters to the Greek, but using ASCII. For C# but same idea in C.
913 to 936 = upper case Greek letters
945 to 968 = lower case Greek letters
Read more at Suite101: Working with the Greek Alphabet and C#: How to Display ASCII Codes Correctly when Creating a C# Application | Suite101.com at this link.
One way to do this is to print a wide string. Unfortunately, Windows needs a bit of non-standard setup to make this work. This code does that setup inside #if blocks.
#include <locale.h>
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
/* This has been reported not to autodetect correctly on tdm-gcc. */
#ifndef MS_STDLIB_BUGS // Allow overriding the autodetection.
# if ( _WIN32 || _WIN64 )
# define MS_STDLIB_BUGS 1
# else
# define MS_STDLIB_BUGS 0
# endif
#endif
#if MS_STDLIB_BUGS
# include <io.h>
# include <fcntl.h>
#endif
void init_locale(void)
// Does magic so that wprintf() can work.
{
// Constant for fwide().
static const int wide_oriented = 1;
#if MS_STDLIB_BUGS
// Windows needs a little non-standard magic.
static const char locale_name[] = ".1200";
_setmode( _fileno(stdout), _O_WTEXT );
#else
// The correct locale name may vary by OS, e.g., "en_US.utf8".
static const char locale_name[] = "";
#endif
setlocale( LC_ALL, locale_name );
fwide( stdout, wide_oriented );
}
int main(void)
{
init_locale();
wprintf(L"μουσάων Ἑλικωνιάδων ἀρχώμεθ᾽\n");
return EXIT_SUCCESS;
}
This has to be saved as UTF-8 with a BOM in order for older versions of Visual Studio to read it properly. Your console also has to be set to a monospaced Unicode font, such as Lucida Console, to display it properly. To mix wide strings in with ASCII strings, the standard defines the %ls and %lc format specifiers to printf(), although I’ve found these don’t work everywhere.
An alternative is to set the console to UTF-8 mode (On Windows, do this with chcp 65001.) and then print the UTF-8 string with printf(u8"μουσάων Ἑλικωνιάδων ἀρχώμεθ᾽\n");. UTF-8 is a second-class citizen on Windows, but that usually works. Try to run that without setting the code page first, though, and you will get garbage.