Bug converting std::tr2::sys::path to std::string? - c++

I am using the Visual Studio 2013 TR2 filesystem library. I am seeing a bug when converting a UNC path to a string:
#include "StdAfx.h"
#include <filesystem>
#include <iostream>
//------------------------------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
namespace fs = std::tr2::sys;
fs::path fsPath = "//server/dir";
std::string sPath = fsPath;
std::cout << sPath.c_str() << "\n";
}
This will output "\server\dir", not "\\server\dir".
Is there a fix or a workaround for this? Am I doing something wrong?

Well I found a workaround that works for me. If I use
sPath = fsPath.string();
I can now pass that string to the std::ifstream constructor. The path string will be "//server/dir" rather than "\\server\dir".

Related

How to change the extension of a file?

I am currently working on project where I need to add some message at the end of a file and then I want to change its extension.
I know how to add the message at the end of the file; my code:
_ofstream myfile;
_myfile.open("check.txt", std::ios_base::app);
_myfile << "Thanks for your help.\n";
How can I change the file's extension?
Actualy, it is very simple:
#include <iostream>
#include <fstream>
#include <cstdio>
using namespace std;
int main(int argc, char* argv[])
{
ofstream fout("test.txt", ios_base::app);
fout << "My cool string";
fout.close();
rename("test.txt", "test.txt1");
return 0;
}

How do I get the locale name using VS2015?

I can get the locale name of my system using the code below compiled in Visual Studio 2013. If I compile this same code in VS2015 I get nothing back! Is this a bug? How do you get your current system locale's name using VS2015 then?
#include "stdafx.h"
#include <iostream>
#include <locale>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << std::locale("").name().c_str() << endl;
}
In VS2015 they made it so the name if the locale is always equal to the argument you pass to the constructor (if it's valid):
// c:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xlocinfo line 360
void _Construct(const string &_Str,
category _Cat)
{ // construct a locale with named facets
bool _Bad = false;
_Init();
if (_Cat != none)
{ // worth adding, do it
_TRY_BEGIN
_BEGIN_LOCINFO(_Lobj(_Cat, _Str.c_str()))
if (_Badname(_Lobj))
_Bad = true;
else
{ // name okay, build the locale
_Locimp::_Makeloc(_Lobj, _Cat, _Ptr, 0);
// The two lines below were added in VS2015
_Ptr->_Catmask = _Cat;
_Ptr->_Name = _Str.c_str(); // <--- Here they set the name forcefully
}
I believe you have to use setlocale() instead:
std::cout << setlocale(LC_ALL, "") << endl;
To have it in std::locale you can do
std::locale loc(setlocale(LC_ALL, ""));
This works in both VS2013 and VS2015.

SHGetFolderPathW not working with japanese username

Im trying to create one file in %APPDATA% using SHGetFolderPathW function. This function I guess is getting chars in unicode. I'm working with Visual Studio 2010 little project. The following code work in english version of win 8 but not in japanese version (username is japanese):
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <windows.h>
#include <Shlobj.h>
#include <tchar.h>
#include <string>
int _tmain(int argc, _TCHAR* argv[])
{
std::wstring output = L"";
WCHAR* folder = new WCHAR[2048];
SHGetFolderPathW(NULL, CSIDL_APPDATA,
NULL, SHGFP_TYPE_CURRENT, folder
);
std::wstring str1 = folder;
str1 += L"\\hola.txt";
std::wcout << str1 << std::endl;
std::string str(str1.begin(), str1.end());
std::cout << str << std::endl;
// Create file in folder
FILE * file;
char *path = new char[str.length()+1];
strcpy(path, str.c_str());
file = fopen (path, "w");
fputs ("Hello World",file);
fclose (file);
system("PAUSE");
return 0;
}
The code is showing good path in English version, but in japanese, this path isn't right. I wonder if I have any way to use SHGetFolderPath in all languages. I'm googling two days but not solution found.
If you have a wide string file path, use wide string version of fopen. This should work:
#include <string>
#include <stdio.h>
#include <Shlobj.h>
#include <tchar.h>
int _tmain(int argc, _TCHAR* argv[])
{
WCHAR folder[MAX_PATH];
SHGetFolderPathW(NULL, CSIDL_APPDATA,
NULL, SHGFP_TYPE_CURRENT, folder
);
std::wstring str1 = folder;
str1 += L"\\hola.txt";
// Create file in folder
FILE * file;
file = _wfopen (str1.c_str(), L"w");
fputs ("Hello World",file);
fclose (file);
return 0;
}

What does boost::locale::generator need?

I'm pretty new to boost and want to use it's boost::locale to make suitable conversations to lower case. But I've got a link problem with boost::locale::generator. I linked my project with libboost_locale-mt.a and switched header search paths correctly, but it isn't enough for some reason. I'm using Xcode, and I got linking mistake on this code:
#include <boost/locale.hpp>
int main(int argc, const char * argv[])
{
using namespace boost::locale;
using namespace std;
generator gen;
std::locale loc = gen("");
locale::global(loc);
cout.imbue(loc);
cout << "This is lower case " << to_lower("Hello World!") << endl;
return 0;
}

How to use wstring and wcout to output Chinese words in Xcode?

I try to run the code blow in Xcode 4.2:
int main(int argc, const char * argv[])
{
locale loc("chs");
locale::global(loc);
wstring text(L"你好");
wcout << text << endl;
return 0;
}
I got a error "Thread 1:signal SIGABRT".
Can you Tell me why the error happen or how to use wstring and wcout to output the Chinese words?
You don't. Mac, like other Unix systems, uses UTF8 while Windows uses "Unicode" (UTF-16).
You can print that perfectly well on Mac by using string and cout instead of wstring and wcout.
ADDENDUM
This sample works great. Compile with g++ and run as-is.
#include <string>
#include <iostream>
using namespace std;
int main(int arg, char **argv)
{
string text("汉语");
cout << text << endl;
return 0;
}
The crash is coming from the call to locale(). This SO answer seems related.
As mentioned by Mahmoud Al-Qudsi, you don't need it as you can use UTF-8 in a normal string object:
#include <string>
#include <iostream>
using namespace std;
int main(int argc, const char * argv[])
{
string text("你好");
cout<<text<<endl;
return 0;
}
Produces:
$ ./test
你好
EDIT: Oops, too late :)