重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

こんにちは。
C言語初心者です。以前この件で質問させていただいたのですがエラーがとれず、もう一度質問してしまいました。

今回は、C言語でレジストリからデータをUTF_16で取得し、UTF_8で表示すると言うプログラミングを組みたいのですがどうしても下記のコードではエラーが出てしまいどうしていいかわかりません。
エラーの内容としては、16から8に変換する部分のutf8Sizeの部分で上手くいっていないようで、、、
どうしたらいいかわからないので、もし知っている方がいればよろしくお願いします。

#include<windows.h>
#include<stdio.h>
void QueryValue(void);

int main(void){
  QueryValue();
  return 0;
}

void QueryValue(void){
  HKEY hkey;
  DWORD ValueType;
  DWORD ValueSize;
  wchar_t Value[1000];

  char *utf8String = 0; // UTF-8 文字列バッファへのポインタ
  size_t utf8Size = 0; // UTF-8 文字列のバイト数 (終端 NUL 含む)
int result;// WideCharToMultiByte() の戻り値

  /*レジストリキーのオープン*/
  RegOpenKeyEx(
    HKEY_LOCAL_MACHINE,
       L"SOFTWARE\\Hitachi\\JP1/RemoteControlManager",
    0,
    KEY_ALL_ACCESS,
    &hkey);
 
  ValueSize = 1000;

  /*レジストリ値の取得*/
  RegQueryValueEx(
    hkey,
    L"ProgramName",
    NULL,
    &ValueType,
    (LPBYTE)Value,
    &ValueSize);
  /*結果の表示(シフトJIS変換’%S’)*/
  if(ValueType == REG_SZ) printf("%S\n",Value);
  else printf("....can't read\n");

/*****************************************************/
  //UTF_16からUTF_8変換を行う
  result = WideCharToMultiByte(
    CP_UTF8,
    WC_NO_BEST_FIT_CHARS,
    Value,
    -1,
    utf8String,
    utf8Size,
    NULL,
    NULL);
  if(result <= 0){
    fprintf(stderr,"UTF_16→UTF_8変換エラー(%lu)\n",GetLastError());
  }
  /*結果の表示()*/
  if(ValueType == REG_SZ) printf("%s\n",utf8String);
  else printf("....can't read\n");
  /*UTF_8文字列バッファを開放する*/
  free(utf8String);
/************************************************/
  /*終了*/
  RegCloseKey(hkey);
}

A 回答 (3件)

あのーーー 前回の回答をちゃんと理解してコードを書いてますか?


http://oshiete.nikkeibp.co.jp/qa3405779.html

>   /*結果の表示(シフトJIS変換’%S’)*/
>   if(ValueType == REG_SZ) printf("%S\n",Value);
>   else printf("....can't read\n");

シフト JIS じゃなくて UTF-8 で表示したいんじゃなかったの?


> /*****************************************************/
>    //UTF_16からUTF_8変換を行う

UTF-8 文字列用のバッファを確保してないし….


>   /*結果の表示()*/
>   if(ValueType == REG_SZ) printf("%s\n",utf8String);

Value が REG_SZ 型であることを確認する前に UTF-16 → UTF-8 変換しようとしてるし….


/*--------------------------------------------------------------------------*/
#include <windows.h>
#include <stdio.h>

int QueryValue(HKEY rootKey, const wchar_t *subKeyName, const wchar_t *valueName)
{
 HKEY hkey = NULL;
 DWORD valueType, valueSize;
 wchar_t value[1000];
 char *utf8String = NULL;
 size_t utf8Size;
 LONG result;

 result = RegOpenKeyEx(rootKey, subKeyName, 0, KEY_READ, &hkey);
 if(result != ERROR_SUCCESS) {
  fprintf(stderr, "RegOpenKeyEx() 失敗 (%ld)\n", result);
  goto Error;
 }

 result = RegQueryValueEx(hkey, valueName, NULL, &valueType, (BYTE*)value, &valueSize);
 if(result != ERROR_SUCCESS) {
  fprintf(stderr, "RegQueryValueEx() 失敗 (%ld)\n", result);
  goto Error;
 }
 printf("valueType: %ld\n", valueType);

 if(valueType == REG_SZ) {
  // UTF-8 文字列のバイト数を取得する.
  result = WideCharToMultiByte(CP_UTF8, 0, value, -1, NULL, 0, NULL, NULL);
  if(result <= 0) {
   fprintf(stderr, "UTF-8 文字列サイズ取得エラー (%ld)\n", GetLastError());
   goto Error;
  }
  utf8Size = (size_t)result;

  // UTF-8 文字列バッファを確保する.
  if((utf8String = malloc(utf8Size)) == NULL) {
   fprintf(stderr, "UTF-8 文字列バッファ確保エラー (%ld)\n", GetLastError());
   goto Error;
  }

  // UTF-16 → UTF-8 変換を行う.
  result = WideCharToMultiByte(CP_UTF8, 0, value, -1, utf8String, (int)utf8Size, NULL, NULL);
  if(result <= 0) {
   fprintf(stderr, "UTF-16 → UTF-8 変換エラー (%ld)\n", GetLastError());
   goto Error;
  }

  // UTF-8 文字列を出力する.
  printf("\"%s\"\n", utf8String);

  free(utf8String);
 } else {
  fprintf(stderr, "Value は REG_SZ 型じゃないよ.\n");
 }
 RegCloseKey(hkey);
 return 0;

Error:
 if(utf8String != NULL) free(utf8String);
 if(hkey != NULL) RegCloseKey(hkey);
 return -1;
}

int wmain(void)
{
 static const wchar_t rootKeyName[] = L"HKEY_LOCAL_MACHINE";
 static const wchar_t subKeyName[] = L"SOFTWARE\\TrendMicro\\PC-cillin\\15\\WSC";
 static const wchar_t valueName[] = L"PCC_Launch";

 printf("%S\\%S\\%S\n", rootKeyName, subKeyName, valueName);
 QueryValue(HKEY_LOCAL_MACHINE, subKeyName, valueName);
 return EXIT_SUCCESS;
}

/*--------------------------------------------------------------------------
実行結果 (UTF-8)
--------------------------------------------------------------------------*/
HKEY_LOCAL_MACHINE\SOFTWARE\TrendMicro\PC-cillin\15\WSC\PCC_Launch
valueType: 1
"ウイルスバスターを起動"
    • good
    • 0

> エラーの内容としては、16から8に変換する部分のutf8Sizeの部分で上手くいっていないようで、、、



MSDNちゃんと読みました?
第6引数に0を指定している(utf8Size = 0)ので、WideCharToMultiByte()の戻り値で必要なバイト数が返されます。

> cchMultiByte
> lpMultiByteStr が指すバッファのサイズをバイト単位で指定します。0 を指定すると、バッファに必要なバイト数が返ります(その場合、lpMultiByteStr が指すバッファは使われません)。
> 戻り値
> cchMultiByte に 0 を指定して関数が成功すると、変換後の文字列を受け取るために必要なバッファのサイズ(バイト数)が返ります。

戻り値で指定されたサイズ以上のメモリを確保し、そのメモリの先頭アドレスを第5引数に、メモリのサイズを第6引数に入れて、再度呼び出します。

   //UTF_16からUTF_8変換を行う
   utf8Size = WideCharToMultiByte(
     CP_UTF8,
     WC_NO_BEST_FIT_CHARS,
     Value,
     -1,
     NULL,
     0,
     NULL,
     NULL);
   utf8String = malloc(utf8Size);
   result = WideCharToMultiByte(
     CP_UTF8,
     WC_NO_BEST_FIT_CHARS,
     Value,
     -1,
     utf8String,
     utf8Size,
     NULL,
     NULL);
    • good
    • 0

答えじゃないんだけれど



iconv を利用するとか そういうのはダメかな?
    • good
    • 0

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