プロが教えるわが家の防犯対策術!

VisualStudio2022を用いて、C言語で記述された(拡張子は.c)以下のプログラムの2行目がエラーになります。

char str1[3] = "あ";//エラーはでません。
char str2[5] = "あい";//E0144 型char[7]の値を使用して型char[5]のエンティティを初期化できません

実行は問題なくできているようです。
VisualStudio2019ではエラーにはなりません。
全角2文字がchar[7]になる理由がわからないのですが、教えていただけないでしょうか

質問者からの補足コメント

  • このファイルを「名前を付けて保存」⇒エンコード付き保存を選択して、保存すると日本語(シフトJIS)と出てきます。日本語(シフトJIS)で保存後も同じ状態なのですが・・・
    バイナリエディタで開いて確認してみても、1文字2バイトです。

      補足日時:2023/12/20 12:56
  • printf("%d\n", sizeof("あい"));
    の結果は5になります。

      補足日時:2023/12/20 13:08
  • すみません。C/C++の項目の中に文字セットが無いのですが。
    ただ、ソースファイル自身はシフトJISになっております。

    No.3の回答に寄せられた補足コメントです。 補足日時:2023/12/20 14:21

A 回答 (4件)

はい、このエラーは特に気にしなくてもよいと思われます。



printf("%d\n", sizeof("あい"));
の結果が5になることは、"あい"の文字コードがシフトJISの「あ」と「い」の2文字分、つまり2バイトであることを示しています。

また、バイナリエディタで開いて確認してみても、1文字2バイトであることも、上記のことから説明がつきます。

つまり、ファイルのエンコードは日本語(シフトJIS)で、文字コードもシフトJISで正しく保存されていることがわかります。

この場合、printf("%s\n", "あい");
の実行結果が「あい」ではなく「あ」と表示されるのは、printf関数の動作の仕方によるものです。

printf関数は、引数に渡された文字列を、画面やファイルなどに出力します。このとき、文字列の文字コードは、プラットフォームの標準文字コードに変換されて出力されます。

Windowsの標準文字コードは、UnicodeのUTF-16LEです。UTF-16LEでは、1文字が2バイトで表現されます。そのため、printf関数でシフトJISの文字列を出力する場合、1文字2バイトのデータが、UTF-16LEの1文字に変換されて出力されます。

このため、printf("%s\n", "あい");
の実行結果は、「あ」と表示されます。

このエラーを解決するには、printf関数の代わりに、fputws関数を使用するとよいでしょう。

fputws関数は、引数に渡された文字列を、画面やファイルなどに出力する関数です。このとき、文字列の文字コードは、そのまま出力されます。

そのため、fputws関数でシフトJISの文字列を出力する場合、1文字2バイトのデータがそのまま出力されます。

具体的には、以下のコードのように記述します。

C
#include <stdio.h>
#include <wchar.h>

int main() {
wchar_t str[] = L"あい";

// printf関数を使用する場合
printf("%s\n", str);

// fputws関数を使用する場合
fputws(str, stdout);

return 0;
}


このコードを実行すると、以下のようになります。

あい
あい
このように、fputws関数を使用すると、printf関数を使用するときと同じように、シフトJISの文字列を正しく出力することができます。
    • good
    • 1
この回答へのお礼

ご丁寧な解説ありがとうございます。
勉強になりました。

お礼日時:2023/12/20 16:30

エラーの原因は、VisualStudio2022がデフォルトでUTF-8エンコードを採用していることです。

そのため、char str2[5] = "あい"; と記述すると、"あい" という文字列は UTF-8 で 6 バイト("あ" の 2 バイト + "い" の 2 バイト + null 終端の 1 バイト)になります。つまり、char[5] の配列には収まりきれないため、エラーが発生します。

VisualStudio2019 では、デフォルトでシフトJIS エンコードを採用しています。そのため、char str2[5] = "あい"; と記述しても、"あい" という文字列はシフトJIS で 3 バイト("あ" の 1 バイト + "い" の 1 バイト + null 終端の 1 バイト)になるため、エラーは発生しません。

この問題を解決するには、VisualStudio2022 でシフトJIS エンコードを指定するか、または char str2[7] のように配列のサイズを大きくしてあげるとよいでしょう。

具体的には、以下のいずれかの方法で解決できます。

VisualStudio2022 で「名前を付けて保存」⇒「エンコード」で「日本語 (シフトJIS)」を選択して保存する。
VisualStudio2022 で「プロジェクトのプロパティ」を開き、「構成プロパティ」⇒「C/C++」⇒「文字セット」で「シフトJIS」を選択する。
char str2[7] のように配列のサイズを大きくする。
バイナリエディタで確認した結果が 1 文字 2 バイトであることは、UTF-8 エンコードで保存されたことを示しています。シフトJIS エンコードで保存すると、1 文字 1 バイトになります。
この回答への補足あり
    • good
    • 1
この回答へのお礼

早速のご回答ありがとうございます。
補足コメントにも書いたのですが、
このファイルを「名前を付けて保存」⇒エンコード付き保存を選択して、保存すると日本語(シフトJIS)と出てきます。日本語(シフトJIS)で保存後も同じ状態なのですが・・・
バイナリエディタで開いて確認してみても、1文字2バイトです。
更に
printf("%d\n", sizeof("あい"));
の結果は5になります。
上記の結果であれば、このエラーは特に気にしなくてもよいのでしょうか

お礼日時:2023/12/20 14:14

試せないので間違えていたらすみません、


文字コードがUTF-8で1文字あたり3バイトになっているからではないでしょうか?

3+3+1(null)で7バイト。
"あ"は恐らく最後のnullがポインタ外に書き込まれているのではないでしょうか。

今の時代、c#ではなくc言語って珍しいですね。
    • good
    • 0
この回答へのお礼

早速のご回答ありがとうございます。
補足コメントにも書かせていただきましたが、
シフトJISで保存されている様です。

お礼日時:2023/12/20 14:16

全角1文字が3バイト、全角2文字と終端文字を合わせて7バイトだとしたら、使用している文字コードがUTF8なのでしょう。



16進数で出力して、自身で確認してみてください。私は確認していません。

・UTF8 文字コード表 3byte
https://orange-factory.com/sample/utf8/code3/e3. …
    • good
    • 0
この回答へのお礼

早速のご回答ありがとうございます。
補足コメントにも書かせていただきましたが、
シフトJISで保存されている様です。

お礼日時:2023/12/20 14:16

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A