ある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で質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# C言語のファイル入力が分かりません 2 2022/05/22 06:35
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- Excel(エクセル) エクセルのマクロについて教えてください。 1 2023/02/06 13:01
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- Visual Basic(VBA) エクセルのマクロについて教えてください。 4 2023/03/02 08:40
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
nullと""、\\0とEOFの違いにつ...
-
16進数を2文字ずつ配列に格納し...
-
C#でstringをポインタとして渡す
-
[C++]WCHARの1文字目しか表示で...
-
c#で他のアプリの文字入力フォ...
-
引用符と二重引用符
-
プログラムによく出てくるst...
-
WSH(VBS)でJSONの文字列を読み...
-
C++で入力した文字列から数字を...
-
[C#.net]正規表現による指定文...
-
Excelシートを固定長のテキスト...
-
_tcscpy_s(wcscpy_s)の第二引数...
-
%dなどの違い
-
Shift_JIS(16進)を文字に変換す...
-
セグメントエラー
-
関数から配列を返すには?
-
VBAのプログラムで、DIAG = 1# ...
-
Integer変数をカラにしたいので...
-
init関数の意味
-
C言語にて構造体のメンバがNULL...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C++で入力した文字列から数字を...
-
nullと""、\\0とEOFの違いにつ...
-
プログラムによく出てくるst...
-
%dなどの違い
-
WSH(VBS)でJSONの文字列を読み...
-
TCL言語で文字列検索方法を教え...
-
C#でstringをポインタとして渡す
-
16進数を2文字ずつ配列に格納し...
-
_tcscpy_s(wcscpy_s)の第二引数...
-
C++で文字列の右端から特定の文...
-
シリアル通信で0x00を送信した...
-
VBA-DLLの引数受け渡しについて
-
数字の入った配列をファイルへ...
-
c#で他のアプリの文字入力フォ...
-
構造体→文字列→構造体 をする方法
-
Shift_JIS(16進)を文字に変換す...
-
バイナリファイル中の日本語文...
-
C言語の課題で困っています;
-
[C++]WCHARの1文字目しか表示で...
-
VB6.0でのバイナリデータの扱い...
おすすめ情報