• ベストアンサー

ConvertINetStringについて

wininetのInternetReadFileでUTF-8のサイトから文字列を受け取ったところ、2バイト文字が文字化けしていました。 ConvertINetStringでUTF-8からShift_JISに変換しようとしていますが上手くいかず困っています。 プログラムは下のようになっています。 DWORD mode = 0, readSize; char src[1024]; BYTE dst[1024]; int srcLen, dstLen; char c[1024]; while( true ) { readSize = 0; ::ZeroMemory(src, sizeof(src)); ::ZeroMemory(dst, sizeof(dst)); // 受信 InternetReadFile( hRequest, src, sizeof(src), &readSize ); if(readSize == 0) break; srcLen = strlen(src); dstLen = sizeof(dst) - 1; // UTF-8からShift_JISへ ConvertINetString(&mode, 65001, 932, src, &srcLen, dst, &dstLen); // BYTEからcharへ for(int i = 0; i < strlen(dst); i++) c[i] = (char)dst[i]; Console::WriteLine("受信:{0}", gcnew String(dst)); } 1.ConvertINetStringでdstに値がちゃんと入らない(「・」みたいなゴミのような文字が入ります) 2.本題とは逸れるのですが、BYTEからcharへの変換はこれでいいのでしょうか? ConvertINetStringが上手くいかない理由が特にわからないので回答をもらえたらありがたいです。

質問者が選んだベストアンサー

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

CLRで組むなら HttpWebRequest、HttpWebResponce、StreamReaderで読み取った方がいいのでは?   HttpWebRequest^ myReq = dynamic_cast<HttpWebRequest^>     (HttpWebRequest::Create( L"URLを記述" ) );   HttpWebResponse^ myRes = dynamic_cast<HttpWebResponse^>     (myReq->GetResponse());   IO::Stream^ strm = myRes->GetResponseStream();   Text::Encoding^ enc = Text::Encoding::GetEncoding( "utf-8" );   IO::StreamReader^ readStream = gcnew IO::StreamReader( strm, enc );   String^ ss = readStream->ReadToEnd();   Console::WriteLine( ss );   myRes->Close();   readStream->Close();   enc = Text::Encoding::GetEncoding("shift-jis");   IO::StreamWriter^ writeStream = gcnew IO::StreamWriter( L"sample04.txt", false, enc );   writeStream->Write( ss );   writeStream->Close();

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

回答No.1

まず、System::Stringは内部的にはUnicode(UTF-16)で扱うので、 Shift_JISに変換してからまたUnicodeにするのは無駄が多い。 (直接UTF-8→Unicodeにすべき) また、UTF-8の文字コードをすべてShift_JISコードに変換することは不可能だったと思います。 (1対1ではない。あらわせる文字の種類の差が結構あるはず。) .NET Frameworkを扱っているのであれば、System::Text::Encodingクラスを扱うとUnicodeの文字列を取得できると思います。 pin_ptrを使って、 (使ったほうがコードが簡単になるとおもう) >char src[1024]; array<BYTE>^ src = gcnew array<BYTE>(1024); pin_ptr<BYTE> psrc = &src[0]; >InternetReadFile( hRequest, src, sizeof(src), &readSize ); InternetReadFile(hRequest, psrc, src->Length, &readSize); System::String^ str = System::Text::Encoding::UTF8->GetString(src); とするとどうでしょうか? (動作検証はしていません。)

参考URL:
http://msdn.microsoft.com/ja-jp/library/744y86tc(VS.80).aspx
全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • c言語 iconv

    msys環境で実行して,指定されたファイルの文字コードをShift-JISに変換して表示するコードを作成しているのですがうまく表示されません.何がいけないのでしょうか.第1引数に変換対象のファイル名,第2引数にファイルの文字コードを指定しています. #include <stdio.h> #include <string.h> #include <iconv.h> int main(int argc, char *argv[]) { iconv_t conv; char src[10000]; char dst[10000]; int src_len = strlen(src); int dst_len = sizeof(dst) - 1; char *buf_in; char *buf_out; FILE *fp; fp = fopen(argv[1], "r"); if(NULL == fp) { printf("ファイルを開けません\n"); } else { while(fgets(src, 10000, fp) != NULL) { buf_in = src; buf_out = dst; /* 変換器を作成 */ conv = iconv_open("Shift-JIS", argv[2]); /* 変換 */ iconv(conv, &buf_in, &src_len, &buf_out, &dst_len); *buf_out = '\0'; /* 終末処理 */ /* 文字コード後の文字列を表示 */ printf("%s\n", dst); } /* 変換器を終了 */ iconv_close(conv); /*ファイルを閉じる*/ fclose(fp); } return 0; }

  • 処理が異常に遅い原因はわかりますか?

    久しぶりに、(perlのXSのために)C言語を組んでみましたが、 以下のコードが、異常に遅いようでした。 (実際には、違う処理ですが、これでも遅くなりましたので、単なる文字コピーです) 例えでいえば、同じことをする数文字のperlの正規表現処理の数100倍の時間がかかっていました。 void hoge(char *dst, char *src, int len) { int i; for(i = 0; i < len; i++) { *dst++=*src++; /* ここをなくすと、爆速になる */ } } ※strlenで当初は試していましたが、ほとんどかわりありません。 どこが、原因でしょうか? 以下のコードは、きちんと爆速で動作してくれます。 void hoge(char *dst, char *src) { for(; *dst++ = *src++;); } コンパイルオプションは gcc -O2 または gcc -O3 で、CPUは、x86_64でなっています。(AMD FX-4170) 処理した文字列は、約100Mバイト分になります。 宜しくお願いします。

  • CRLFをLFに変換したい

    テキストファイルを 1)SJIS → UTF-8 2)CRLF → LF に変換させたいのですが、1)はうまく出来たのですが、 2)がうまくいかず困っています Set Src = CreateObject("ADODB.Stream") Src.Open Src.Type = 2 Src.Charset = "Shift_JIS" Src.LoadFromFile "test.txt" Set Dst = CreateObject("ADODB.Stream") Dst.Open Dst.Type = 2 Dst.Charset = "UTF-8" Dst.LineSeparator=10 Src.CopyTo Dst Src.Close Dst.SaveToFile "utf-out.txt", 2 Dst.Close 改行コードが何も変化しません。 どうすればよいか教えてください。 ADODBではじめからファイルに書き込んでいく方法でもかまいません。

  • strcpy関数について(\0のコピー)

    '\0'のsrcからdstへのコピーについて考えて見たのですが、 char *strcpy(char *dst,const char *src) { int i=0; for(i=0;src[i]!='\0';i++) dst[i]=src[i]; dst[i]=src[i];←1 return dest; } このプログラムではfor文の真偽値の判定の段階では'\0'がsrcからdstにコピーできていないので1のdst[i]=src[i]でコピーする必要がありますが、以下のようにプログラムを変更すると char *strcpy(char *dst,const char *src) { int i=0; for(i=0;(dst[i]=src[i])!='\0';i++) ; return dest; } (dst[i]=src[i)の代入式の段階でsrcからdstにコピーしその後でfor文の真偽値の判定をするので、真偽値判定前にdst側配列に'\0'が入っていると言う考えでこのプログラムを理解して良いのでしょうか。なにかミスしそうなプログラムですが、考え方として、私の言っている事は正しいでしょうか。宜しく回答願います。

  • iconv_open失敗

    いつもお世話になっております。 OpenIndiana NetBeansIDE 7.1でc++のプログラミングをしているのですが、下記コードで SHIFT-JISを指定すると iconv open: Invalid argument となってしまいます。 SHIFT-JISの文字コード関係の何かのインストール等が不足しているのでしょうか。 locale -a というコマンドを実行してみたのですが、 UTF-8に関係しそうなものは入っていたのですが、SHIFT-JIS(PCK?) のようなものは入ってなさそうでした。 どなたかご教授よろしくお願いいたします。 どなたかご教授よろしくお願いいたします。 int main(int argc, char** argv) { int ret; // ret = convert("UTF-8", "EUC-JP",//成功 // ret = convert("UTF-8", "SHIFT_JIS", ret = convert("UTF-8", "SHIFT-JIS", "日本語テストメッセージおはよう", outbuf, sizeof(outbuf)); if (ret) { printf("%s\n", outbuf); } else { printf("Oops!\n"); } return 0; } int convert(char const *src, char const *dest, char const *text, char *buf, size_t bufsize) { iconv_t cd; size_t srclen, destlen; size_t ret; cd = iconv_open(dest, src); if (cd == (iconv_t)-1) { perror("iconv open"); return 0; } srclen = strlen(text); destlen = bufsize - 1; memset(buf, '\0', bufsize); ret = iconv(cd, &text, &srclen, &buf, &destlen); if (ret == -1) { perror("iconv"); return 0; } iconv_close(cd); return 1; }

  • C言語です。コレを使ってなにかプログラミングを組んでください

    C言語です。コレを使ってなにかプログラミングを組んでください よろしくお願いします 何でも構いません #include<stdio.h> void str_copy( char dst[], char src[] ) { int i; for (i =0; src[i] != '\0'; i++) { dst[i] = src[i]; } dst[i]= '\0'; }

  • 自作のstrcatが動かない件

    お世話になります。 Wikiペディアに掲載されていたstrcatの実装例(http://ja.wikipedia.org/wiki/Strcat#.E5.AE.9F.E8.A3.85.E4.BE.8B)をそのまま使って、 mystrcatを作ってみましたが、結果が空白になってしまいます。 [ソース] #include <stdio.h> #include <string.h> #include <stdlib.h> char *mystrcat(char *s1, const char *s2) { char *p = s1; while(*s1++); while(*s1++ = *s2++); return p; } void main(){ char *dst; char *p;; char *src1 = "Hello"; char *src2 = "World"; dst = malloc(strlen(src1)+strlen(src2)+1); printf("%s\n",mystrcat(dst,src1)); printf("%s\n",mystrcat(dst,src2)); free(dst); } [実行結果] 空白2行 [期待していた動作] Hello HelloWorld 何が間違っているのか教えていただけると助かります。 標準のstrcatを使うとHelloとHelloWorldが表示されます。 よろしくお願いします。

  • ポインタ勉強中です。しかも実行するとおかしいです。

    <本に載ってたソース> #include<stdio.h> #include<string.h> int main() { char msg[20]; char *str=NULL; int i; int cnt; str=&msg[0]; printf("文字を入力してください"); scanf("%s",&str); cnt=strlen(msg); str=msg+cnt; for(i=cnt;i>=0;i--){ printf("%c",*(str--)); } printf("\n"); return 0; } char *str=NULL;は、ポインタstrを空にするということでしょうか? いつもながらstrlenとsizeofが混じります。 sizeofがバイトの大きさで、strlenが、文字数でしたっけ?

  • 2次元配列の動的確保

    ある画像を読み込むため、その画像を格納できる幅、高さを持った配列を動的に確保しようと考えています。 幅をxsize、高さをysizeで次のように記述しました。 unsigned char **src; int i; src = (unsigned char**)malloc(sizeof(unsigned char*) * ysize); src[0] = (unsigned char*)malloc(sizeof(unsigned char) * xsize * ysize); for(i=1; i<ysize; i++) src[i] = (src[0] + i * xsize); わざわざポインタのポインタを使用したのは、動的に確保した配列を2次元的なアクセスをしたかったためです。 画像の読み込み時は fread(src[0], sizeof(unsigned char), xsize * ysize, fp); としています。 上に記述したソースは問題なく動作しました。 しかし、上の場合だと全ての配列を連続して確保することができません。つまりsrcでmallocを一回、src[0]でmallocを一回使っているため、ポインタの配列の直後に配列を確保する保障がありません。そこでいっぺんに確保することを考えました。 unsigned char **src; int i; src = (unsigned char **)malloc(sizeof(unsigned char *) * ysize + sizeof(unsigned char) * xsize * ysize); for(i=0; i<ysize; i++) src[i] = (unsigned char *)(src + sizeof(unsigned char *) * ysize + i * xsize); このように組み上げ、読み込み時は上のfreadと同様に記述したところエラーが出てしまいました。 やはり一行目のmallocで無理やりsizeof(unsigned char *) * ysize + sizeof(unsigned char) * xsize * ysize分確保するのは失敗だったのでしょうか?

  • ポインタ変数を用いた配列の反転操作。

    strSrcの文字列を逆順にしてstrDstに格納し、 逆順にした文字列を表示するプログラムを自分なりに考えて、 作成したのですが、途中で行き詰ってしまいました。 src=strSrc;とdst=strDst;辺りが上手くいっていないようなので どなたかどのように記述すれば良くなるのかご教授お願いします。 また、他の問題点などもあればどうかご指摘お願いします。 #include <stdio.h> /* 文字列反転関数 引数: char *src : 反転させる文字列 char *dst : 反転させた結果を書き込む文字列 返値: なし */ void reverseStr(char *src, char *dst) { src=strSrc; dst=strDst; /*文字列の末尾を指すまでインクリメント*/ while(src != 0){ src++; } /*『配列strDstの番地の値』を『配列strSrcの番地の値』に上書き*/ while(*dst != 0){ *dst=*src; src--; dst++; } *dst=0; } /* メイン関数 引数: なし 返値: int 正常終了時 0 */ int main(void) { char strSrc[] = "abcdefghijkl" ; char strDst[] = "01234567890123456789" ; reverseStr( strSrc, strDst ) ; printf("%s\n", strDst ) ; return( 0 ); }