including stdio when calling WriteConsole results in error - c++

#include <stdio.h>
#include <windows.h>
using namespace std;
int main() {
char s[] = "Hello\n";
HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE);
unsigned long cChars;
WriteConsole(stdout, s, lstrlen(s), &cChars, NULL);
}
result: error: declaration of '_iob' as array of references
but when I comment out stdio.h, it compiles ok. What's wrong here ?
Compiler is MinGW.

Depending on the platform, stdout is probably a macro, so better not use that name. Replace
HANDLE stdout = ...
with
HANDLE out = ...
and then
WriteConsole(out, ...
stdout is defined in stdio.h, that's why it fails only when this file is included. But to be safe, never use that name for any self-defined variable.

the stdout is already defined by system.. try changing it to _stdout or something else

Related

Unicode output not showing

I'm trying to learn Unicode programming in Windows.
I have this simple program:
#include <iostream>
#include <string>
int main()
{
std::wstring greekWord = L"Ελληνικά";
std::wcout << greekWord << std::endl;
return 0;
}
However, it outputs nothing. Any ideas how to make it output Greek?
I tried adding non-Greek letters, and that didn't work quite right either.
The first thing to try is to make the program not dependent on the encoding of the source file. So use Unicode escapes not literal Unicode letters
std::wstring greekWord = L"\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC";
Having the incorrect encoding in the source file is only one thing of many things that could be preventing you from printing Greek. The other obvious issue is the ability of your terminal to print Greek letters. If it can't do that, or needs to be set up correctly so that it can then nothing you do in your program is going to work.
And probably you want to fix the source code encoding issue, so that you can use unescaped literals in your code. But that's dependent on the compiler/IDE you are using.
If you are outputting your cout to a normal console then the console doesn't usually support unicode text like greek, try setting it up for unicode text or find another way to output your data, like txt files or some gui,
There are two way to do this.
The old, non-standard Microsoft way is as follows:
#include <fcntl.h>
#include <io.h>
int main()
{
_setmode(_fileno(stdout), _O_U16TEXT);
_setmode(_fileno(stdin), _O_WTEXT);
// your code here
}
You will fild this everywhere, but this is not necessarily a good way to solve this problem.
The more standards-compliant way is as follows:
#include <locale>
int main()
{
std::locale l(""); // or std::locale l("en_US.utf-8");
std::locale::global(l); // or std::wcout.imbue(l); std::wcin.imbue(l);
// your code here
}
This should work with other modern compilers and operating systems too.
TRY this it works with me :
#include
#include <io.h>
#include <fcntl.h>
using namespace std;
int main() {
_setmode(_fileno(stdout),_O_U16TEXT);
wcout<<L"Ελληνικά";
setlocale(LC_ALL,"");
return 0;
}

Is it possible to unify std::wstring behavior in VSVC and GCC?

Here a little code that reads a line from UFT-8 file:
#include <iostream>
#include <io.h>
#include <fcntl.h>
#include <locale>
#include <fstream>
#include <codecvt>
int main()
{
_setmode(_fileno(stdout), _O_U8TEXT);
auto inputFileStream = std::wifstream("input.txt");
const auto utf8Locale = std::locale(std::locale(), new std::codecvt_utf8<wchar_t>());
inputFileStream.imbue(utf8Locale);
std::wstring line;
std::getline(inputFileStream, line);
std::wcout << line << std::endl;
inputFileStream.close();
return 0;
}
When I build it with the Visual Studio Visual C++ compiler, I got the next result:
test τεστ тест
as expected.
By when I use MinGW with the GCC compiler, I got
琀攀猀琀 쐃딃쌃쐃 䈄㔄䄄䈄
As you understand, it's not the expected result.
Does any simple way exist to fix the output for GCC to the expected string?
OR
Does any simple way exist to use UTF-8 for both MSVC and GCC?
Answer (thanks for Igor Tandetnik and Remy Lebeau):
Seems, we must specify endian mode explicitly, because MSVC and GCC have different defaults. So
new std::codecvt_utf8<wchar_t, 0x10ffff, std::little_endian>()
should be used.
Fixed code:
#include <iostream>
#include <io.h>
#include <fcntl.h>
#include <locale>
#include <fstream>
#include <codecvt>
int main()
{
_setmode(_fileno(stdout), _O_U8TEXT);
auto inputFileStream = std::wifstream("input.txt");
const auto utf8Locale = std::locale(std::locale(), new std::codecvt_utf8<wchar_t, 0x10ffff, std::little_endian>());
inputFileStream.imbue(utf8Locale);
std::wstring line;
std::getline(inputFileStream, line);
std::wcout << line << std::endl;
inputFileStream.close();
return 0;
}
For your second question, one option is to limit the use of utf16 and std::w-prefixed stuff to the cases when you need to exchange utf16-encoded strings with the operating system. This happens when you receive arguments in wmain, open file with _wfopen, call Windows API function, etc. Otherwise, you would store, get from the user and return to the user utf8 strings using char type (char*, std::string, etc). Conversion between utf8 and utf16 can be done with MultiByteToWideChar and WideCharToMultiByte, bypassing the retarded c++ encoding api. The place where this does not work well is console input/output. Overall, you can output utf8 to the console if the user sets chcp 65001 and a ttf font. At least in Windows 7, you will also have to make sure not to split a character between two write calls, otherwise it will not print correctly (this also implies you cannot use std::cout, because msvcrt will call putc for every byte separately, and you'll need to use puts, fprintf, etc instead); I heard that this was fixed in Windows 10, but cannot confirm. Reading utf8 from the console with file api does not work as far as I know; if you want that, you'd need to detect that stdin is attached to a console and use console api instead.

constructor opens a file with a given filename c++

In my code below errors occur and the program will not run, I am required to make a Constructor that must open the file with the given filename. If the filename does not exist then it Prints an error message and terminates the program.
Below is the code that I have done so far in C++:
#include "ReadWords.h"
#include <iostream>
#include <cstdlib>
using namespace std;
ReadWords::ReadWords(const char filename[])
{
wordfile.open(filename);
if (!wordfile)
{
cout << "cannot make " << filename << endl;
exit(1);
}
}
void ReadWords::close()
{
wordfile.close();
}
Why dont you try including fstream to the top of your file and see if that works
I suppose wordfile is of type std::fstream. If your ReadWords.h #includes <fstream>, it should work (compiles and works as expected).
By the way, it's a bad practice to use using namespace std;.
Also, since you use C++, take a look at std::string. It's safer than using plain char* or char[].

LD_PRELOAD with boost fileystem library

I am trying to intercept open system call in Linux. It works fine with other libraries but doesn't wotk with boost libboost_fileystem. Here is my code (stripped down for readability).
#include <boost/filesystem/fstream.hpp>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <stdarg.h>
#include <stdio.h>
using namespace std;
using namespace boost::filesystem;
typedef int (*open_func_type)(const char * pathname, int flags, ...);
int open(const char *path, int flags, ...)
{
va_list arg;
mode_t mode = 0;
if (flags & O_CREAT)
{
va_start(arg, flags);
mode = va_arg(arg, mode_t);
va_end(arg);
}
//some stuff here
open_func_type open_func = (open_func_type) dlsym(RTLD_NEXT, "open");
return open_func(path, flags, mode);
}
int main()
{
boost::filesystem::fstream build_path;
build_path.open("/tmp/test.txt", ios::in);
//other stuff
return 0;
}
I stepped though the code using gdb, my open implementation doesn't get called. But doing strace shows the open system call being called. If I call other library functions that call open, I see my implementation getting called. Anything that I am doing wrong here? I am dynamically linking with boost libraries.
I gave sometime to figure it out and found that internally boost calls std::basic_filebuf open which in turn calls fopen. fopen seems to call open system call in the kernel without calling open library call (it would be nice if somebody could point it out why). I intercepted fopen call and this works fine now. If large file support is used, fopen64 also needs to be implemented.

How do I find the current directory?

I am trying to read a file which I read previously successfully.
I am reading it through a library, and I am sending it as-is to the library (i.e. "myfile.txt").
I know that the file is read from the working/current directory.
I suspect that the current/working directory has changed somehow.
How do i check what is the current/working directory?
Since you added the visual-c++ tag I'm going to suggest the standard windows function to do it. GetCurrentDirectory
Usage:
TCHAR pwd[MAX_PATH];
GetCurrentDirectory(MAX_PATH,pwd);
MessageBox(NULL,pwd,pwd,0);
Boost filesystem library provides a clean solution
current_path()
Use _getcwd to get the current working directory.
Here's the most platform-agnostic answer I got a while ago:
How return a std::string from C's "getcwd" function
It's pretty long-winded, but does exactly what it's supposed to do, with a nice C++ interface (ie it returns a string, not a how-long-are-you-exactly?-(const) char*).
To shut up MSVC warnings about deprecation of getcwd, you can do a
#if _WIN32
#define getcwd _getcwd
#endif // _WIN32
This code works for Linux and Windows:
#include <stdio.h> // defines FILENAME_MAX
#include <unistd.h> // for getcwd()
#include <iostream>
std::string GetCurrentWorkingDir();
int main()
{
std::string str = GetCurrentWorkingDir();
std::cout << str;
return 0;
}
std::string GetCurrentWorkingDir()
{
std::string cwd("\0",FILENAME_MAX+1);
return getcwd(&cwd[0],cwd.capacity());
}