質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

2247閲覧

char型配列文字列をchar16_t型変数に格納したい。

退会済みユーザー

退会済みユーザー

総合スコア0

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/05/19 05:20

編集2021/05/19 12:33

提示コードの/////コメント内部のコードですが const char型配列で来た文字をchar16_t型配列変数に代入したいのですが文字が格納されませんこれはなぜでしょうか?戻り値は1です。

エラー[ 1が カウント されます。次の カウント を含むか、有効なマルチバイト文字を入力します。 返される値は、マルチバイト文字を完成するのに必要なバイト数です。 Wchar が null ポインターでない場合、それに相当するワイド文字は wchar に格納されます。 ]

参考サイト1: https://www.ibm.com/docs/ja/zos/2.3.0?topic=functions-mbrtoc16-convert-multibyte-character-char16-t-character
参考サイト2: https://programming-place.net/ppp/contents/c/appendix/reference/mbrtoc16.html

イメージ説明

cpp

1#include <iostream> 2int main() 3{ 4 const char text[] = "テスト"; 5 6 7 wchar_t txt[20] = { '\0' }; 8 9 int f = mbrtowc(txt, text, (size_t)strlen(text), nullptr); 10 std::cout << f << std::endl; 11 12 13 for (int i = 0; txt[i] != '\0'; i++) 14 { 15 std::cout << txt[i] << std::endl; 16 } 17 18 19 20 21 return 0; 22}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

K_3578

2021/05/19 05:21

>どうすればいいのでしょか? 前まで直ってたのにまた日本語下手になってないか?
退会済みユーザー

退会済みユーザー

2021/05/19 11:13 編集

戻り値的には、変換できてますよね? コードを質問文にとは書きましたが、タイトルにある「mbrtoc16()関数を使って」ないのにこの内容は意味不明ではないでしょうか もう少し考えて質問を編集していただければと思います
guest

回答2

0

ベストアンサー

setlocale が必要なのではありませんか?
それと mbrtowc は 1文字の変換なので、文字数分繰り返さないといけないのでは?
wchar_t を出力するのは、cout ではなく、wcout かもしれません。

C++

1#include <iostream> 2#include <locale> 3 4int main() 5{ 6 setlocale(LC_CTYPE, ""); 7 const char text[] = "テスト"; 8 wchar_t txt[20] = { L'\0' }; 9 int i, j, f; 10 for (i = 0, j = 0; text[j]; i++, j += f) 11 f = mbrtowc(txt + i, text + j, MB_CUR_MAX, nullptr); 12 txt[i] = L'\0'; 13 for (i = 0; txt[i] != L'\0'; i++) 14 std::wcout << txt[i] << std::endl; 15}

追記
= { L'\0' } で初期化しているから、txt[i] = L'\0'; の行は不要でした。

追記2
文字列を変換したいのに、文字変換の mbrtowc を使うのは面倒です。
mbstowcs を使えば次のようになります。

C++

1#include <iostream> // wcout, endl 2#include <cstdlib> // mbstowcs 3#include <clocale> // setlocale 4using namespace std; 5 6int main() 7{ 8 setlocale(LC_CTYPE, ""); 9 const char text[] = "テストtest"; 10 wchar_t txt[20]; 11 int n = mbstowcs(txt, text, 20); 12 wcout << n << endl; 13 for (int i = 0; txt[i]; i++) 14 wcout << txt[i] << " " << hex << int(txt[i]) << endl; 15}

実行結果

text

17 2テ 30c6 3ス 30b9 4ト 30c8 5t 74 6e 65 7s 73 8t 74

投稿2021/05/19 17:30

編集2021/05/21 04:20
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazuma-s

2021/05/20 08:43

何のコメントもなしに解決済みになっていますが、setlocale が何か理解していますか? setlocale の詳しい説明をお願いします。
guest

0

元々のコードの mbrtoc16() の使い方について

エラーコードは-1です。なぜアクセスエラーが発生するのでしょうか?

エラーコード-1の原因は、入力 text の中身が不正だからです。コメントのやりとりによると:

入力の文字列リテラルを u8"テスト" のように書くことが可能なら簡単に済む話ですが、入力がシフトJISのテキストファイルであるとか、いろいろと都合はあるでしょう。であれば、Visual Studio の環境であれば mbrtoc16() は諦めるしかありません。

Windows での wchar_t char16_t WCHAR

Windows ではこれらは同じものとして扱って構いません。他のプラットフォームではダメです。

mbrtowc() について

コメントのやりとりで、私はこれを mbstowcs() と勘違いしていました。mbrtowc() は1つの wchar_t 文字を得るための関数で、文字列を対象にするには不適切でした。
利用するとしても、第3引数のmbstate_t*nullptrにしてはいけません。詳しくはMicrosoftのサンプルを参照してください。

シフトJIS文字列をUTF-16にするには?

mbstowcs()などを使ってください。

Windowsであれば、MultiByteToWideChar()もコード例がたくさんあって参照しやすいかもしれません。

投稿2021/05/19 05:30

編集2021/05/19 15:14
int32_t

総合スコア20909

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/05/19 06:56

"テスト"という文字列が入っています。
int32_t

2021/05/19 07:01

開発環境は Visual Studio ですか? その文字列はシフトJISですか? UTF-8 ですか?
退会済みユーザー

退会済みユーザー

2021/05/19 07:05

Visual studio でANSIです
int32_t

2021/05/19 07:12

私はVisual Studioを持っていないので ANSIと言われても正確なことはわかりませんが、strlen(text) が 6 ならシフトJIS、strlen(text) が 9 なら UTF-8 です。 UTF-8 の場合は mbrtoc16() が -1 を返さないでしょうから、シフトJISなのでしょうね。ということは mbrtoc16() は使えないので、回答のリンク先ページの指示に従ってください。
退会済みユーザー

退会済みユーザー

2021/05/19 07:43 編集

int f = mbsrtowcs_s(&size,txt,sizeof(text),&text,sizeof(text),nullptr); 関数を使いましたが画面に何も表示されません。
int32_t

2021/05/19 07:49

リンク先には mbsrtowcs_s() を使えなんて書いてないですよね。 「To convert non-UTF-8 multibyte characters to UTF-16 LE characters, use the mbrtowc, mbtowc, or _mbtowc_l functions」 よく読みましょうね。
int32_t

2021/05/19 08:01

locale は、日本語版Windowsを使っていて特殊な設定をしていなければ何も設定しなくて大丈夫なはずです。 あと、Visual Studio が対応しているかどうか知りませんが、Text::Draw() の引数を u8"テスト" と書くと mbrtoc16() のままで動くかもしれません。
退会済みユーザー

退会済みユーザー

2021/05/19 08:03

const char16_t型として引数を取りu"テスト"という引数を入力すると普通に表示されるのですが引数では普通に"テスト"と入力して文字を表示させたいので質問しました。
int32_t

2021/05/19 08:06

> 普通に"テスト"と入力して文字を表示させたい 了解です。
退会済みユーザー

退会済みユーザー

2021/05/19 08:10

提示サイトの関数を色々入れて実験しましたがどれも表示されません
int32_t

2021/05/19 08:13

「色々」じゃあ何を失敗しているのか指摘できないので、mbrtowc() を使ったコードを開示してください。
退会済みユーザー

退会済みユーザー

2021/05/19 08:17

wchar_t txt[10000] = { '\0' }; int f = _mbtowc_l(txt, text, strlen(text),nullptr); です。
int32_t

2021/05/19 08:20

誰も _mbtowc_l() なんて書いてないですよね。よく読みましょうね。
退会済みユーザー

退会済みユーザー

2021/05/19 08:23

wchar_t txt[10000] = { '\0' }; int f = mbtowc(txt, text, strlen(text)); size_t size; //int f = mbsrtowcs_s(&size,txt,sizeof(text),&text,sizeof(text),nullptr); 等を試しました。
int32_t

2021/05/19 08:24

私は「mbrtowc() を使ったコード」と書きました。よく読みましょうね。
退会済みユーザー

退会済みユーザー

2021/05/19 08:27

すいませんでした。 int f = mbrtowc(txt, text, sizeof(text),nullptr); としましたが文字の枠だけが表示されます。
int32_t

2021/05/19 08:29

使い方を間違えています。sizeof(text) でポインタのサイズを渡すのではなく、文字列の長さを渡してください。
退会済みユーザー

退会済みユーザー

2021/05/19 08:32

変更しましたが文字の枠だけが表示されます。しっかりビルドもして実行しているのですがなぜでしょうか?
int32_t

2021/05/19 08:38

forループの中で txt[i] を表示するかデバッガで覗いてみてください。12486, 12473, 12488 の3つが出ていれば mbrtowc() は成功しています。
退会済みユーザー

退会済みユーザー

2021/05/19 08:43

131とう数字が表示されました。失敗でしょうか?
int32_t

2021/05/19 08:58

失敗してますね。 main()の中でmbrtowc()だけするプログラムを作って動作確認できませんか?
退会済みユーザー

退会済みユーザー

2021/05/19 09:08

#include <iostream> int main() { const char text[] = "テスト"; wchar_t txt[20] = { '\0' }; //int f = mbtowc(txt, text, strlen(text)); int f = mbrtowc(txt, text, (size_t)strlen(text), nullptr); std::cout << f << std::endl; for (int i = 0; txt[i] != '\0'; i++) { std::cout << txt[i] << std::endl; } return 0; } というテストプロジェクトを作って実験しましたが戻り値は1 で中の数値は131です。
退会済みユーザー

退会済みユーザー

2021/05/19 10:21

そのコードを質問文に書いた方がいいのでは 現状のコードじゃ不要な部分の方が多いので
退会済みユーザー

退会済みユーザー

2021/05/19 11:50 編集

結局代理デバッグしてるだけで、文字コードの知識を身に付けさせず進めさせるならまた同じような事で足止め食うだけだと思いますが。デバッグ方法のヒントくらいは与えてもいいとは思いますけど、本人がデバッグして失敗成功判断出来る知識を身に着けてやるべきで、int32_t さんが失敗とか成功判断してるのは、正直本人のためにならないと思いますよ。
int32_t

2021/05/19 14:55

私が勘違いしていた部分があり、mbrtowc() をお勧めしたのは不適切でした。 回答を更新します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問