2013-07-09 2 views
3

Я пытаюсь реализовать приложение, в котором я хотел бы, чтобы пользователи вводили ударные символы в командной строке. Я пытаюсь преобразовать массив символов в вектор wstring.Как преобразовать акцентированные символы из командной строки в wstring?

Я нахожусь в Linux.

Вот что я получил до сих пор:

#include <vector> 
#include <string> 
#include <cstring> 
#include <iostream> 

std::vector<std::wstring> parse_args(int argc, const char* argv[]){ 
    std::vector<std::wstring> args; 

    for(int i = 0; i < argc - 1; ++i){ 
     auto raw = argv[i+1]; 

     wchar_t* buf = new wchar_t[1025]; 
     auto size = mbstowcs(buf, raw, 1024); 

     args.push_back(std::wstring(buf, size)); 
     delete[] buf; 
    } 

    return std::move(args); 
} 

int main(int argc, const char* argv[]){ 
    auto args = parse_args(argc, argv); 

    for(auto& arg : args){ 
     std::wcout << arg << std::endl; 
    } 
} 

Он работает, как ожидался с нормальными персонажами, но не с акцентированными символами. Например, если я:

./a.out Ménage 

он выходит из строя:

terminate called after throwing an instance of 'std::length_error' 
    what(): basic_string::_S_create 
[1] 30564 abort  ./a.out Ménage 

Исключение приходит из конструктора wstring, потому что размер = 18446744073709551615 (size_t - 1 я думаю), который, кажется, указывает, что существует неожиданный персонаж.

Я не вижу, что это происходит не так?

Что я делаю неправильно?

EDIT: Это будет лучше

Если добавить

setlocale(LC_ALL, ""); 

В начале программы, она не откажет, но не выводит странный символ:

M�nage 

может это проблема с моей консолью сейчас?

+0

Вы на окнах? –

+2

@PreetKukreti: Windows редко имеет исполняемые файлы, называемые 'a.out'. – MSalters

+0

Это может оказаться полезным: http://stackoverflow.com/questions/6400597/why-does-mbstowcs-return-invalid-multibyte-character – hmjd

ответ

2

Функция mbstowcs использует кодировку символов из текущей локали. Вы не устанавливаете локаль, поэтому используется локаль по умолчанию «C»; языковой стандарт по умолчанию поддерживает только символы ASCII. Кроме того, вы должны проверить возвращаемое значение mbstowcs, поэтому оно не сработает без вашего ведома.

Чтобы устранить эту проблему, установите локаль в программе:

#include <clocale> 

... 

int main(int argc, const char* argv[]){ 
    setlocale(LC_ALL,""); // Use locale from environment 
    .... 
} 
+1

Или в C++, 'std :: locale :: global (std :: locale())'. – 0x499602D2

+0

Я просто попробовал это сейчас. Это немного лучше. Он не падает, но он выводит M nage вместо Ménage. –

+0

Вы работаете с локали UTF-8 и терминалом с поддержкой UTF-8? Запустите 'locale', чтобы проверить текущий язык. – Joni

Смежные вопросы