The following program compiles in Visual Studio 2008 under Windows, both with Character Set
"Use Unicode Character Set" and "Use Multi-Byte Character Set". However, it does not compile under Ubuntu 10.04.2 LTS 64-bit and GCC 4.4.3. I use Boost 1.46.1 under both environments.
#include <boost/filesystem/path.hpp>
#include <iostream>
int main() {
boost::filesystem::path p(L"/test/test2");
std::wcout << p.native() << std::endl;
return 0;
}
The compile error under Linux is:
test.cpp:6: error: no match for ‘operator<<’ in ‘std::wcout << p.boost::filesystem3::path::native()’
It looks to me like boost::filesystem under Linux does not provide a wide character string in path::native(), despite boost::filesystem::path having been initialized with a wide string. Further, I'm guessing that this is because Linux defaults to UTF-8 and Windows to UTF-16.
So my first question is, how do I write a program that uses boost::filesystem and supports Unicode paths on both platforms?
Second question: When I run this program under Windows, it outputs:
/test/test2
My understanding is that the native() method should convert the path to the native format under Windows, which is using backslashes instead of forward slashes. Why is the string coming out in POSIX format?
Your understanding of native is not completely correct:
Native pathname format: An implementation defined format. [Note: For POSIX-like operating systems, the native format is the same as the generic format. For Windows, the native format is similar to the generic format, but the directory-separator characters can be either slashes or backslashes. --end note]
from Reference
This is because Windows allows POSIX-style pathnames, so using native() won't cause problems with the above.
Because you might often get similar problems with your output I think the best way would be to use your preprocessor, i.e.:
#ifdef WINDOWS
std::wostream& console = std::wcout;
#elif POSIX
std::ostream& console = std::cout;
#endif
and something similar for the string-class.
If you want to use the wide output streams, you have to convert to a wide string:
#include <boost/filesystem/path.hpp>
#include <iostream>
int main() {
boost::filesystem::path p(L"/test/test2");
std::wcout << p.wstring() << std::endl;
return 0;
}
Note that AFAIK using wcout doesn't give you Unicode output on Windows; you need to use wprintf instead.
Try this:
#include <boost/filesystem/path.hpp>
#include <iostream>
int main() {
boost::filesystem::path p("/test/test2");
std::wcout << p.normalize() << std::endl;
return 0;
}
Related
I'm trying to run this code and im a beginner at this im really struggling I don't know what to do.
NB: A "MinGW" version of Code::Blocks was used here.
#include <stdio.h>
#include <omp.h>
int main() {
printf ("Hello, world:");
#pragma omp parallel
printf (" %d", omp_get_thread_num ());
printf ("\n");
return 0;
}
Change a debugger setting in the following way.
From the Settings menu click on Debugger..., then on the left of the screen select Default, a debugger type. This should show Executable paths set to:
C:\MinGW\bin\gdb.exe
change this to:
C:\Program Files\Codeblocks\MinGW\bin\gdb.exe
You should then be able to use the debugger.
NB: Other Information
The above type of fix is required if you install the "MinGW" version of 'Code::Blocks 20.03' on Windows, using 'codeblocks-20.03mingw-setup.exe' ( the version relevant on 8th April 2021 , with the default installation type used ).
I developed a simple qt app on windows to test the qt Chinese UTF-8 encoding-format:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
QString strMessage = QString::fromLocal8Bit("我是UTF8编码的文件:");
qDebug() << strMessage;
return a.exec();
}
and my main.cpp file encoding format is UTF-8 without BOM, but when I run the app on windows, the app print string is "鎴戞槸UTF8缂栫爜鐨勬枃浠讹細" which I expect is "我是UTF8编码的文件:",it seems the string "我是UTF8编码的文件:" is converted to GB2312 encoding-format so shows the wrong string "鎴戞槸UTF8缂栫爜鐨勬枃浠讹細" in runtime,and the string "我是UTF8编码的文件:" shows right string "我是UTF8编码的文件:'' when the app runs on macos, I don't know why?
how to let the string "我是UTF8编码的文件:" show right on windows platform, thanks a lot!
On Windows, printing UTF-8 to the console is not automatic. You need to execute this command first in the console to change to codepage 65001 (which is the UTF-8 Windows codepage):
chcp 65001
You also need to set a font that offers Chinese characters. On Windows 10, that's the "NSimSun" font. However, the Windows console has a neat function where it automatically switches the font if you set a Chinese codepage (like 936). So you can actually programmatically run these commands using the standard library system() function. The chcp command produces output though. To hide it, redirect the output to nul.
#include <cstdlib>
// ...
int main(int argc, char *argv[])
{
#ifdef Q_OS_WIN
// Temporary codepage change so we get an automatic font change.
system("chcp 936 > nul");
// Change to UTF-8.
system("chcp 65001 > nul");
#endif
QApplication a(argc, argv);
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
QString strMessage = QString::fromUtf8("我是UTF8编码的文件:");
qDebug() << strMessage;
return a.exec();
}
(As a side note, you should use QString::fromUtf8() since you know the text is in UTF-8.)
I have a new project where I created a HelloWorld.cpp Source file.
But when I am running it in Start without dedugging mode (CTRL+ F5), it opens the console and closes automatically.
#include <iostream>
#include<stdlib.h>
#ifdef _WIN32
#define WINPAUSE system("pause")
#endif
using namespace std;
void main()
{
cout << "Hello, World!" ;
}
Mr. Patel, did you try using the second solution on that linked question and then tried to use the run without debugging option? The Visual Studio will only keep the command prompt open if you set the subsystem option in the linker to console. If it is not set, the window will close as soon as the program finishes running.
At any rate, note that this will only work if you run your program from inside Visual Studio, running your .exe directly will still have it close as soon as possible. If you want your program to wait on the user, you would need to do it yourself (at least as far as I know). A very simple solution would be to write your main function like this:
int main (int argc, char* argv[]) {
...//Your code goes here.
std::cout << "Enter any character to end the program.\n";
char end;
std::cin >> end;
return(0);
}
Note that to use the cin and cout streams, you should include the iostream header in your code.
When 32bit app like java or python is trying to open c:\windows\system32\bash.exe this file simply not found.
How ever, it works perfectly if process ir 64bit. I've created a simple C app to check how it works.
#include <stdio.h>
#include <windows.h>
int main(int argc, char *argv[]) {
char* path;
OFSTRUCT junk;
if (argc != 2) {
printf("provide path to file");
return 1;
}
path = argv[1];
if( fopen( path, "r")) {
printf("OK: Runtime reports file exists");
} else {
printf("ERR: Runtime reports file does not exist");
}
printf("\n");
if (OpenFile(path, &junk,OF_EXIST) != HFILE_ERROR) {
printf("OK: Win32API reports file exists");
} else {
printf("ERR: Win32API reports file does not exist");
}
return 0;
}
It reports OK/OK when compiled and linked as x64 and ERR/ERR when compiled as x86. How could it be? Does there is some way to "hide" file from 32 bit apps in Windows?
This is the file system redirector in action.
In most cases, whenever a 32-bit application attempts to access %windir%\System32, the access is redirected to %windir%\SysWOW64.
So, your 32-bit application is looking for C:\Windows\SysWOW64\bash.exe instead, which presumably doesn't exist.
The recommended way to override it:
32-bit applications can access the native system directory by substituting %windir%\Sysnative for %windir%\System32. WOW64 recognizes Sysnative as a special alias used to indicate that the file system should not redirect the access.
Note that there are similar redirections for the registry as well.
I'm trying to figure out how I can test if a file is being redirected to itself, e.g. .\command.exe file1 > file1
In the *nix world, I'd just use something like this:
// Language agnostic...
if (file_dev == out_dev && file_ino == out_ino) {
printf("%s\n", "same file!");
}
But in Windows, if I try to do this:
// This (language) is Go...
// create fileStat...
// now stat stdout
outStat, err := os.Stdout.Stat()
// error check
if os.SameFile(fileStat, outStat) {
fmt.Println("same file!")
}
...I get the IncorrectFunction error.
I read this (How to check if stdout has been redirected to NUL on Windows (a.k.a. /dev/null on Linux)?) question, and from what I gather you can't stat stdout?
This is a mostly language agnostic question -- I can translate whatever to Go (the language I'm using). I'm mostly concerned about how, using Windows' ABI (API?), I would find where stdout is being redirected to.
This answer is Windows-specific but as you've tagged windows I figure that's ok.
I can't help with Go, but in C/C++ you can do something like this:
#include <tchar.h>
#include <Windows.h>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
wchar_t chPath[MAX_PATH];
if (GetFinalPathNameByHandle(GetStdHandle(STD_OUTPUT_HANDLE), chPath, MAX_PATH, 0))
std::wcout << L"stdout = " << chPath << std::endl;
else
std::cout << "stdout not redirected" << std::endl;
return 0;
}
GetFinalPathNameByHandle will fail if stdout is a console handle, but if it's been redirected to a file it will return the file path.
You can call HANDLE GetStdHandle( DWORD stdHandle ) with STD_INPUT_HANDLE and STD_OUTPUT_HANDLE to open the file handle.
Then call DWORD GetFileType( HANDLE hFile ) to check if the returned type is FILE_TYPE_DISK
Finally, call
DWORD WINAPI GetFinalPathNameByHandle( _In_ HANDLE hFile, _Out_ LPTSTR lpszFilePath, _In_ DWORD cchFilePath, _In_ DWORD dwFlags );
to obtain the file pathname and compare the names for equivalency.
Well, first up, I don't think your method in UNIX-land is actually going to protect you.
By the time your code gets to checking devices and inodes, the shell has already truncated the file. It is responsible for processing the output redirections and it does this before your program even starts, so that you're given a fresh file for your output.
I suspect you'd have the same problem in Windows in that cmd.exe will truncate your file before your script even started running.
Having said that, I believe at some point you're going to have to trust that the user knows what they're doing :-)
The other alternative is, of course, not to do output redirection but instead to require the input and output files as arguments:
cmd.exe myscipt myscript
That way, you could detect if the user was going to write to the input file (using canonicalised file names or inodes) and prevent it.
Although that still won't prevent the user from doing something silly like:
cmd.exe myscipt >myscript
blowing away your script before you get a chance to notify them they should have provided two arguments rather than one.
I think the bottom line is, if the user does output redirection, there's no way for your program to catch it before it's too late.