1

I'm trying to print the text "Ääkkösiä ruutuun." to console with c++. I have windows 7 and am using Code::Blocks editor. Searching on the subject I found that maybe these sort of lines would help

_setmode(_fileno(stdout), _O_U16TEXT);
wstring s{L"Ääkkösiä ruutuun."};
wcout<<s<<endl;

But when I try to compile it, I get the error: _fileno was not declared in this scope.

I have all these includes:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <stdexcept>
#include <cmath>
#include <sstream>
#include <fstream>
#include <codecvt>
#include <locale>
#include <fcntl.h>
#include <io.h>
#include <stdio.h>
#include <cstdio>
#include <ostream>

what am I missing?

Also, one other thing I tried was locale, but then locale::empty wasn't found! Why doesn't my c++ have anything in it?

EDIT Here is a picture of what my program is doing now.

It prints out just the first letter (Ä). What happens to the rest?

Ääkkösiä ruutuun, perkele!

Ok, it seems that setmode sets it so that only one letter gets printed. (Even trying to print normal texts with multiple commands, just results in a single letter.) Without it the scandinavian letters don't print correctly, thought. They look like this:

enter image description here

ploosu2
  • 413
  • 6
  • 15
  • According to Microsoft, `_fileno` is defined in ``. According to IBM and others, it's `fileno` without an underscore that is defined. – Tim Randall Feb 07 '19 at 16:01
  • I've tried both, neither found. By the way, why does one need the .h in stdio as it is not needed for example in "#include ? – ploosu2 Feb 07 '19 at 16:05
  • I think you need to look at how your development environment is confgured. It sounds like your include paths are not defined. As for `` versus ``, well, the former is standard and the latter ought to work too. – Tim Randall Feb 07 '19 at 16:07
  • you do not need `fileno(stdout)` for this. There's a `STDOUT_FILENO` (which is normally equals 1) located in `unistd.h`. – Vovanium Feb 07 '19 at 16:09
  • @Vovanium Ok, That was found. But how about _O_U16TEXT? – ploosu2 Feb 07 '19 at 16:11
  • I just checked, and `_fileno` is declared in `stdio.h` on my Visual Studio 2017 setup. – Paul Sanders Feb 07 '19 at 16:13
  • Ok, I found that that _O_U16TEXT is the number 0x00020000, so why not just put that in. Hence my code is: _setmode(STDOUT_FILENO, 0x00020000); It compiles and runs, but... I get just the signle letter "Ä" printed out. Where does the rest go? – ploosu2 Feb 07 '19 at 16:23
  • @ploosu2 C standard headers (such as `stdio.h`) have names ending in `.h`. The C++ standard library headers such as `string` don't have any suffix. – eerorika Feb 07 '19 at 16:23
  • @ploosu2 I don't know about `_O_U16TEXT`. `fileno` etc is common POSIX stuff, but `_setmode` and its flags seem to be Microsoft specific. – Vovanium Feb 07 '19 at 16:24
  • Halleluja, I got it to work! The magic line is setlocale(LC_CTYPE, ".OCP"); – ploosu2 Feb 07 '19 at 17:10
  • Possible duplicate of [\_O\_WTEXT, \_O\_U16TEXT, \_O\_U8TEXT - are these modes possible in mingw compiler, are there any workarounds?](https://stackoverflow.com/questions/8871540/o-wtext-o-u16text-o-u8text-are-these-modes-possible-in-mingw-compiler-ar) – Marc.2377 Sep 11 '19 at 07:15

2 Answers2

1

The answer you found is for Visual Studio, not Code::Blocks.

While the C standard specifies what should in in <stdio.h>, it only specifies a minimum. Implementors may add their own functions, and should do so using an _ (underscore prefix). This is why you should NOT use that prefix. You don't know what you'll break. Microsoft clearly signaled their non-standard extensions using the correct prefix.

The answer is tagged C++, but C++ inherits the contents of <stdio.h> from C.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • It certainly broke something, since it only prints out one letter. Thankfully not permanently since commenting out that setmode-call reverts it back the garbled scandis but at least it prints everything. Ok, so now I'm trying to search for a Code::Blocks solution. I just don't know what words to use. One would think this is a solved problem of just printing out unicode stuff. – ploosu2 Feb 07 '19 at 16:56
  • @ploosu2: The Unicode people themselves seem to be occupied by adding emojis. I can't entirely blame Microsoft nor Code::Blocks for this. – MSalters Feb 07 '19 at 17:08
  • @ploosu2: If you're willing to set up Code::Blocks to use the mingw-w64 toolchain, you'll have `_fileno`. Alternatively, you can just define it yourself (check the question marked as duplicate in comments to OP). – Marc.2377 Sep 26 '19 at 02:25
-1

The line

setlocale(LC_CTYPE, ".OCP");

works!

A complete example:

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <fstream>

using namespace std;

wstring readFile(const char* filename) {
    wifstream wif(filename);
    locale myLoc("");
    //locale utf8_locale(locale(), new gel::stdx::utf8cvt<true>);
    wif.imbue(myLoc);
    basic_stringstream<wchar_t> wss;
    wss << wif.rdbuf();
    return wss.str();
}

int main() {
    setlocale(LC_CTYPE, ".OCP");
    wstring contents = readFile("test.txt");
    wcout<<L"Does anything get printed out at all???"<<endl;
    //wcout <<contents<<endl;
    wstring s{L"Ääkkösiä ruutuun."};
    wcout<<s<<endl;
    wcout<<L"Näkyykö äkköset?"<<endl;
    return 0;
}

The text read from file (utf-8) still doesn't print correctly, though. It should be

Hei!
Täällä on kaksi riviä.

ä's go awry there.

Output:

output with LC_TYPE_OCP

ploosu2
  • 413
  • 6
  • 15
  • 1
    That limits you to the OEM codepage, and if it's like MSVC there's a double translation to the console output codepage, which happens to default to OEM as well. Only Windows 10 supports UTF-8 in this case, and that's beta and not the default configuration. In Windows 7 it will be a legacy codepage, limited to about 250 characters for non-Asian locales. If you can't get your C/C++ library to work with the console's Unicode API, you can call `WriteConsoleW` directly with UTF-16LE text. – Eryk Sun Feb 07 '19 at 21:14
  • `setlocale()` does a very different thing than what you were doing in the question. See my answer [here](https://stackoverflow.com/a/40337240/3258851), and also the question I linked as possible duplicate in your question. – Marc.2377 Sep 11 '19 at 07:16