

あるWebサイトによると以下のプログラムでディレクトリ内の
ファイル一覧を表示できるそうだ。たしかにファイル一覧を
表示できた。しかし、わたしの電子計算機上では、
ファイル名の1文字目しか表示できない。
なおfd.cFileNameはWCHARという配列のようだ。fd.cFileName[2]のように
文字位置を指定すれば、1文字目以降を取得できる。
Windows XP SP3
Visual C++ 2008 Express Edition
ーーーーーーーーーーーーーーーーーーーーーーーーー
#include <stdio.h>
#include <string>
#include <iostream>
#include "windows.h"
using namespace std;
int main(int argc, char *argv[])
{
HANDLE hFind;
WIN32_FIND_DATA fd;
FILETIME ft;
SYSTEMTIME st;
wstring FName;
FName = L"*.*";
/* 最初のファイル検索 */
hFind = FindFirstFile(FName.c_str(), &fd);
/* 検索失敗? */
if(hFind == INVALID_HANDLE_VALUE) {
printf("検索失敗\n");
return(0); /******** エラー終了 ********/
}
while(FindNextFile(hFind, &fd)){
FileTimeToLocalFileTime(&fd.ftLastWriteTime, &ft);
FileTimeToSystemTime(&ft, &st);
printf("ファイル名: %s", fd.cFileName);
if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
printf("(ディレクトリ)");
}
printf("\n短いファイル名: %s\n", fd.cAlternateFileName);
printf("ファイルサイズ: %d\n", fd.nFileSizeLow);
printf("更新日: %04d/%02d/%02d %02d:%02d:%02d\n\n",st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
}
/* 検索終了 */
FindClose(hFind);
return(0);
}
No.1ベストアンサー
- 回答日時:
printfで%sを指定したばあい、char型配列に格納された文字列を表示することになります。
WCHAR(wchar_t)型配列にUnicodeで格納された文字列である場合、
Unicodeは2バイトで1文字であるため、たとえば、「ABC」という文字列である場合
0x0041 0x0042 0x0043 0x0000
という文字コード配列になります。
これを無理やりchar型の配列としてみなすようにすると、
0x41 0x00 0x42 0x00 0x43 0x00 0x00 0x00
というようなShift_JISの文字コードの配列になります。
C言語の文字列の終端は'\0'が出てくるまでということなので、
最初の1文字で終わりになってしまうわけです。
回避策としては、
・printfを使用せず、wchar_tに対応したwprintfを使用する。(setlocaleが必要)
・%sではなく%Sを使用する。
のどちらかでしょうか。
もっとも、Win32 APIを使う以上、文字列は大抵TCHARで扱うことが多いので、
TCHAR用の関数を全体的に使ったほうが良いでしょうけど。
No.2
- 回答日時:
printfは基準がMBCS(マルチバイト)になっています
つまり0x00が文字列の終端として使われ、文字もバイト単位でアクセスされます
L"AB"の場合 ワイド文字ですと 0x41 0x00 0x42 0x00 0x00 0x00 といった並びになるので最初の Aしか出力されません
ワイド文字版の wprintfですと文字も16ビット単位でアクセスされるので "AB"が出力されます
これを回避するのであれば ヘッダーの tchar.h をインクリュードして
WIDE文字、MBCS文字共通のマクロでコーディングします
文字列リテラルは _T("ABC") または _TEXT("TEXT")
printfの場合 _tprintf
といった具合にして見ましょう
マルチバイトモードで一時的にワイド文字列を出力したいなら
%sではなく %S で 書式指定しましょう
また、VC++プロジェクトの設定の文字セットを『Unicode文字列を使う』を『マルチバイト文字セットを使う』に変更する
といった対処をしましょう
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
アルファベットの出て来た回数
-
sprintf関数での文字列変換につ...
-
%dなどの違い
-
[C++]WCHARの1文字目しか表示で...
-
_tcscpy_s(wcscpy_s)の第二引数...
-
TCL言語で文字列検索方法を教え...
-
WSH(VBS)でJSONの文字列を読み...
-
Excelですべての組合せ(重複組...
-
C言語において、 配列要素をひ...
-
C言語 配列の長さの上限
-
CStringからchar*への型変換に...
-
isalpha()関数について
-
配列を使わずに、変数名を動的...
-
C言語の配列のサイズ
-
Integer変数をカラにしたいので...
-
Run-Time Check Failure #3とい...
-
リッチテキストボックスの中身...
-
C# Listを使わずに2次元配列の...
-
define で 配列
-
allocってなんですか?
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
nullと""、\\0とEOFの違いにつ...
-
C#でstringをポインタとして渡す
-
TCL言語で文字列検索方法を教え...
-
シリアル通信で0x00を送信した...
-
C++で入力した文字列から数字を...
-
16進数を2文字ずつ配列に格納し...
-
プログラムによく出てくるst...
-
WSH(VBS)でJSONの文字列を読み...
-
_tcscpy_s(wcscpy_s)の第二引数...
-
%dなどの違い
-
VBA-DLLの引数受け渡しについて
-
C言語の問題です。
-
c#で他のアプリの文字入力フォ...
-
構造体→文字列→構造体 をする方法
-
int型での文字列の扱いについて
-
[C++]WCHARの1文字目しか表示で...
-
char a[]="thank you for comin...
-
VB6.0でのバイナリデータの扱い...
-
Excelシートを固定長のテキスト...
-
C#のGUIからサーバー側のPHPへ...
おすすめ情報