WriteFileで数値が書き込めません

このQ&Aのポイント
  • WriteFileで数値を書き込もうとしても、数値が書き込めません。文字列は問題なく書き込まれます。
  • Visual C++ Express EditionとWindows Vista SP2の環境で、WriteFileで数値を書き込もうとした際に問題が発生します。
  • 試しに使用したコードやハンドルの取得は正常であり、戻り値も正常に返りますが、ファイルを開くと数値が書き込まれていません。
回答を見る
  • ベストアンサー

WriteFileで数値が書き込めません。

又、お世話になります。タイトルの通り、WriteFileで数値を書き込もうとしておりますが、数値が書き込めません。戻り値は、一応1(いち)が帰ってきますが、例えば、そのファイルをメモ帳に関連付けて開くと、何も書き込まれておりません。因みに、文字列は何ら問題なく、書き込まれております。コードの一部を載せておきますので、お気づきの点が御座いましたら、ご教授して頂ければと思います。よろしくお願い致します。尚、環境はVisual C++ Express EditionとWindows Vista SP2です。 //CreateFile(ハンドルは、しっかり取れています。) HANDLE DShReDraw = ::CreateFile(_T("DSLotoRedraw.tmp"),                  ENERIC_READ | GENERIC_WRITE,                  FILE_SHARE_READ |  FILE_SHARE_WRITE, NULL,                  OPEN_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL); char DSLongBuff[] = _T("12345678901"); LONG DSnPosX = 0L; LONG DSnPosY = 0L; errno_t DSErr = _i64toa_s((long)DSnPosX, DSLongBuff, 12, 10); size_t DSMojisuu = strlen(DSLongBuff); DWORD DSdw = (DWORD)DSMojisuu; OVERLAPPED DSOverLapped; ::ZeroMemory(&DSOverLapped, sizeof(OVERLAPPED)); DSOverLapped.Offset = DSdw; //最初は、これで試しました。でも、駄目でしたので、この下のを使用 //(DSfBoolは、1を返します。) /*BOOL DSfBool = ::WriteFile(DShReDraw, (LPCVOID)&DSnPosX, (LONG)(sizeof(LONG)), DSlpDW, &DSOverLapped);*/ //これでも駄目でした。(DSfBoolは、1を返します。) BOOL DSfBool = ::WriteFile(DShReDraw, (LPCVOID)&DSnPosX, (LONG)DSdw, DSlpDW, &DSOverLapped);

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

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.3

>ただ、後で32ビットの最高値が入るとして、それを文字列に変換したらこの位は必要かと思い、この変数を用意致しました。 0xffffffff=4294967295ですから、10桁ということになるでしょう。 # 当然文字列として扱うために'\0'の分も必要ですが。 >しかし、作成されたファイルをメモ帳に関連付けて中をのぞいてみますと、0(ゼロ)が書き込まれるべき場所が、空白に成っているのです。 書き込まれたのは「数値」の0であって、「数字」の'0'ではありません。 よって、メモ帳で開いても「0」は見えません。 書き出したいのは「数値」なんですよね? バイナリエディタで確認して下さい。 「数字」で書き出したいのであれば、WriteFile()の第2引数はDSLongBuffになるかと。 あと、オーバーラップは不要かと思われますがどうなんでしょう?

Dominico1
質問者

お礼

Wr5さん、どうも有難うございました。 >書き出したいのは「数値」なんですよね? >バイナリエディタで確認して下さい。 メモ帳で開いても数値は見えないのですね。非常に、申し訳御座いませんでした。バイナリエディッターで開いたところ、数値のゼロが書き込まれているのを確認致しました。 >あと、オーバーラップは不要かと思われますがどうなんでしょう? 確かに、今現在はテスト用ですので必要無いのですが、これから先大きなファイルを取り扱う予定でありますので、実際にファイの書き込みが終了したかどうかを後々判断する為に、取りあえずOVERLAPPEDを設定致しております。 Wr5さん、誠に有難う御座いました。私の勘違い及び勉強不足でご迷惑をお掛けいたしました。これから、もっともっと、勉強していきたいと思います。

その他の回答 (2)

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.2

補足要求しつつ要求内容を書き忘れた… 『結果としてファイルにどんな【値】が書き込まれていることを期待していますか?』 一応、リトルエンディアンってことていいのでしょうか? # とはいえ12桁の数値だと32ビットを越えているかと思いますが。

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.1

気のせいでなければ…ですが… なんか無茶苦茶のような気がするのですが…… >char DSLongBuff[] = _T("12345678901"); >LONG DSnPosX = 0L; >errno_t DSErr = _i64toa_s((long)DSnPosX, DSLongBuff, 12, 10); http://msdn.microsoft.com/ja-jp/library/0we9x30h(VS.80).aspx より… DSnPosXの0を文字列としてDSLongBuff[]に「入れ」ます。 これは意図した動作ですよね? _T("12345678901")も文字列リラテルの意味がほとんどありませんが。 >BOOL DSfBool = ::WriteFile(DShReDraw, (LPCVOID)&DSnPosX, (LONG)DSdw, >DSlpDW, &DSOverLapped); オーバーラップは置いておきますが… http://msdn.microsoft.com/ja-jp/library/cc429856.aspx DSnPosXの変数が確保されている場所から、「1バイト」書き出します。 そして、謎のDSlpDWにそのサイズ(1)を書き出します。 ちなみに、DSnPosXは0なので書き出したファイルには1バイトの0が書き込まれている…ハズです。 CreateFile時にFILE_FLAG_OVERLAPPED フラグは無いみたいなので… オーバーラップは使われていない??

Dominico1
質問者

補足

Wr5さん、お世話に成ります。 <DSnPosXの0を文字列としてDSLongBuff[]に「入れ」ます。 <これは意図した動作ですよね? はい、ゼロが書き込まれればこちらの意図した結果です。 <_T("12345678901")も文字列リラテルの意味がほとんどありませんが。 すみません。単に数え間違えました。ただ、後で32ビットの最高値が入るとして、それを文字列に変換したらこの位は必要かと思い、この変数を用意致しました。 <DSnPosXの変数が確保されている場所から、「1バイト」書き出します。 <そして、謎のDSlpDWにそのサイズ(1)を書き出します。 確かに、ブレークポイントを設定し変数を見ますと、DSlpDWに0(ゼロ)が1バイト書き出されています。しかし、作成されたファイルをメモ帳に関連付けて中をのぞいてみますと、0(ゼロ)が書き込まれるべき場所が、空白に成っているのです。最初は、ゼロだから空白なのかとも思いましたが、ReadFile()で読み込まれませんので、やはり書き込まれていないと、判断しました。 以上、何卒よろしくお願い致します。

関連するQ&A

  • 非同期のプロセス間通信(パイプ)で全データ受信する

    こんにちは。 非同期のプロセス間通信(パイプ)で詰まっています。 環境はWindowsで処理系はC++(Win32)です。 スレッドを用意して、 hPipe = ::CreateFile( L"\\\\.\\pipe\\pipename", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL ) ; で作成し、OVERLAPPED構造体を // ZeroMemory( &so, sizeof( OVERLAPPED )) ; sOverlapped.hEvent = ::CreateEvent( NULL, FALSE, FALSE, NULL ) ; として、 const size_t bufsize = 16 ; BYTE     buffer[ uBufSize ] ; DWORD    dwNumberOfBytesRead ; bRet = ::ReadFile( hPipe, buffer, bufsize, &dwNumberOfBytesRead, &so ) ; で読み込みをしています。ReadFile関数はすぐ戻りbRetはFALSEで返ってくるため、GetLastErrorを調べて、 switch( ::GetLastError()) {   case ERROR_IO_PENDING :     bRet = ::GetOverlappedResult( hPipe, &so, &dwNumberOfBytesRead, FALSE ) ;     break ; } としてWaitForMultipleObjectsでsOverlapped.hEventがシグナル状態になったら取得したデータの処理をしています。 シグナル状態になるならないに関わらず、上記のReadFileとGetOverlappedResultはループでぐるぐる回しています。 上記の状態で短いデータならよかったのですが、上記のReadFileで読み込み最大サイズの16バイトを超えてしまとうと、 残りの部分のみしか取得できませんでした。 0123456789ABCDEFabcdefg というデータを受信しようとしたとき、後半のabcdefgだけしか取得できませんでした。 すべてのデータを正しく取得するにはどのようにしたらよいのでしょうか?

  • WriteFileで送信できたかの確認方法は?

    シリアルポートで非同期でバイナリを送信するプログラムを作成しています。 以下のソースでバイナリを送信したつもりなのですが、本当に送信できているのか分りません。 送信が完了したのか確認するにはどうしたいいでしょうか? よろしくお願いします。 COMのオープン、DCBの設定は恐らく問題ないので、 WriteFileの周辺を抜粋します。 OVERLAPPED old; ZeroMemory( &old, sizeof(old) ); old.Offset = 0; old.OffsetHigh = 0; old.hEvent = NULL; char wbuf[7] = {0x02,0x0C,0x01,0x00,0x31,0x15,0x1A}; DWORD wbyte; if(!WriteFile(hCom,wbuf,(DWORD)sizeof(wbuf),&wbyte,&old)){ if(ERROR_IO_PENDING == GetLastError()){ GetOverlappedResult(hCom,&old,&wbyte,TRUE); } else MessageBox("エラー"); }

  • WriteFileの引数について

    APIを学習中の初心者です。 サンプルコードにあったのですが、test0623.txt のテキストを作成し、「abcde」と書き込むというものです。 Const GENERIC_WRITE = &H40000000 Const GENERIC_READ = &H80000000 Const FILE_ATTRIBUTE_NORMAL = &H80 Const CREATE_ALWAYS = 2 Const OPEN_ALWAYS = 4 Const INVALID_HANDLE_VALUE = -1 Private Declare Function CloseHandle Lib "kernel32" ( _ ByVal hObject As Long) As Long Private Declare Function WriteFile Lib "kernel32" ( _ ByVal hFile As Long, lpBuffer As Any, _ ByVal nNumberOfBytesToWrite As Long, _ lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Long) As Long Private Declare Function CreateFile Lib "kernel32" _ Alias "CreateFileA" (ByVal lpFileName As String, _ ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, _ ByVal lpSecurityAttributes As Long, _ ByVal dwCreationDisposition As Long, _ ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long Sub test1() Dim hFile As Long Dim FileName As String Dim Sampledata() As Byte Dim BytesToWritten As Long Dim SC As Long FileName = "test0623.txt" SC = StrConv("abcde", vbFromUnicode) hFile = CreateFile(FileName, GENERIC_WRITE Or GENERIC_READ, _ 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0) SC = WriteFile(hFile, Sampledata(0), _ UBound(Sampledata), BytesToWritten, 0) Call CloseHandle(hFile) End Sub とあったのですが質問は以下の通りです。    (1) SC = WriteFile(hFile, Sampledata(0), UBound(Sampledata), BytesWritten, 0) で、な ぜ、lpBuffer(第1引数)にSampledata(0)を指定すれば、ファイルに書き込むべきデータを保持しているバッファへのポインタになるのか?またSampledata(0)のように配列にする理由が不明? (2) SC = WriteFile(hFile, Sampledata(0), UBound(Sampledata), BytesWritten, 0) で、なぜ、  nNumberOfBytesToWrite(第2引数)に UBound(Sampledata)を指定すれば、ファイルに書き込むべきバイト数になるのか?ここで、0を指定すると、何も書き込まないらしい。 (3) SC = WriteFile(hFile, Sampledata(0), UBound(Sampledata), BytesWritten, 0) で、なぜ、lpNumberOfBytesWritten(第3引数)に何の値も格納していない BytesWritten を記述しているのか?MSDNライブラリには、「関数から制御が返ると、この変数に、実際に書き込まれたバイト数が格納されます。」とあるので、指定しなくてよいのか?    (4) Pathを指定していないが、なぜか、C:\Users\123\Documents に作成される。 以上です。よろしくお願いします

  • WriteFileのエラー995は何が原因?

    <プログラム環境> Windows XP VC++6.0 MFC AppWizard(exe) ダイアログベース <症状> 以下のコード部分は、これまでエラーは無かったのですが、 他の部分をいろいろといじった結果以下のコードでエラーが出るように なりました。 HANDLE hCom;//COMポートのハンドル OVERLAPPED old;//構造体 unsigned char ucBuf[];//送信する内容 DWORD dwByte;//送信するバイト数 //上記変数は宣言後、正しい値を入れています。 BOOL blRet;//実行結果 if(WriteFile(hCom,ucBuf,dwByte,NULL,&old) == 0){ blRet = GetLastError(); } を実行後、blRetの結果を確認すると995で、 「スレッドが終了したか、またはアプリケーション要求によって、I/O 処理が中止されました。」 が出ました。 <質問> このエラーは何が原因でしょうか? 宜しければご指摘の程よろしくお願いします。

  • 大きなファイルの読み書き

    WindowsXP + SDKにてC++の開発をしています。 ディスクから50MB程度のファイルを読んで処理を施しまた書き戻すという事をやっていますが HANDLE handle; char fileName[256]; strcpy(fileName , "ファイル名"); handle = CreateFile(fileName , GENERIC_READ , NULL , NULL , OPEN_EXISTING , FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL ,NULL); としてファイルのオープンには成功するのですが OVERLAPPED ol; unsigned long size; unsigned long readSize; unsigned char *mem; ReadFile(handle , mem , readSize , &size , &ol) としていざ読もうとすると "ERROR_NO_SYSTEM_RESOURCES"が戻ってきて処理がとまってしまいます。 今までまったく同じコードで1~12MB程度のファイルは問題なく読み書き出来ていたのですが50Mのファイルを扱おうとしたところ問題が発生してしまいました。 FILE_FLAG_NO_BUFFERING と FILE_FLAG_OVERLAPPEDをはずすと読めるのですが余りにもアクセスが遅いので使い物になりません。 何か回避方法がありましたら御教授願います。

  • 実行時にエラーが出ます(;。;)

    hFile = CreateFile("1.txt",GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL); この文章で実行時エラーが出ます。初心者なのでよろしくお願いします。 C言語です。

  • SMART情報

    OS:Windows7 VS2008 SP1 http://www.usefullcode.net/2007/02/hdd.htmlをみて SMART情報を取得するプログラムを書いています http://www.usefullcode.net/2007/02/hdd.htmlの下の方からプロジェクトがDLできて 試しにビルドして(通りました) 実行してみたのですが、 //OSによってCreateFile処理を変える if(sVerInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { hIoCtrl = ::CreateFile(_T("\\\\.\\SMARTVSD"), 0,0,0,CREATE_NEW, 0, 0); //Windows 9x } else { CAtlString strDevice; strDevice.Format(_T("\\\\.\\PhysicalDrive%d"),nDeviceNo); hIoCtrl = ::CreateFile(strDevice,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL); int Error=0; Error=GetLastError(); char DebugStr[256]; wsprintf(DebugStr,"Error=%d",Error); MessageBox(NULL,DebugStr,"File Error",MB_OK); } if(hIoCtrl == INVALID_HANDLE_VALUE) { MessageBox(NULL,"hIoCtrl == INVALID_HANDLE_VALUE Error","hIoCtrl == INVALID_HANDLE_VALUE Error",MB_OK); return false;//********ここでfalseでreturnされてしまう。********* } ここでCreateFileエラーがでてしまい(GetLastError=2です。) falseでreturnされてしまい、うまくHDD情報が取得できません。 そもそもstrDevice.Format(_T("\\\\.\\PhysicalDrive%d"),nDeviceNo);の第一引数が_T("\\\\.\\PhysicalDrive%d")と指定されていますが、 ここには何を指定すべきなのでしょうか。これが分かればできそうな気がします。

  • WriteFile関数

    WriteFile関数 C言語でWindowsプログラミングを学習中です。 2点ご質問です。 LPTSTR型のbufferには(1)のように文字列を格納して、 画面に表示しています。 ファイルに保存するために改行は「\r\n」に置き換えているので、 画面上ではもちろん改行されません。 Editコントロールを使用すれば簡単にいくと思いますが、 このような方法で画面上にも改行・ファイルにも改行という方法はありますか? さらに(2)で保存したファイルを開くと文字と文字の間に半角のスペースが 入ってしまいます。 ごくたまに入らない時もありますが、文字列の一部しか表示されません。 これはUNICODEとマルチバイトの関係なのでしょうか? UNICODEを定義しています。 マルチバイトを定義してしまうとGetSaveFileName関数が エラーになってしまうので・・・ ご教授お願いします。 (1) case WM_CHAR: if(wp==VK_BACK){ if(!iCount) return 0; iCount--; InvalidateRect(hWnd,NULL,TRUE); }else if(wp==VK_RETURN){ buffer[iCount++]='\r\n'; InvalidateRect(hWnd,NULL,TRUE); return 0; }else{ buffer[iCount++]=(TCHAR)wp; InvalidateRect(hWnd,NULL,TRUE); } return 0; case WM_PAINT: hdc=BeginPaint(hWnd,&ps); GetClientRect(hWnd,&rc); DrawText(hdc,buffer,iCount,&rc,DT_WORDBREAK); EndPaint(hWnd,&ps); return 0; ・ ・ ・ ・ (2) int MySave(LPTSTR buffer,HWND hWnd) { OPENFILENAME ofn; HANDLE hFile; TCHAR szFile[MAX_PATH]; TCHAR szFileTitle[MAX_PATH]; DWORD dwAccBytes; memset(&ofn,0,sizeof(OPENFILENAME)); ofn.lStructSize=sizeof(OPENFILENAME); ofn.hwndOwner=hWnd; ofn.lpstrFilter=TEXT("text(*.txt)\0*.txt\0All files(*.*)\0*.*\0\0"); ofn.lpstrFile=szFile; ofn.lpstrFileTitle=szFileTitle; ofn.nFilterIndex=1; ofn.nMaxFile=MAX_PATH; ofn.nMaxFileTitle=MAX_PATH; ofn.Flags=OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY; ofn.lpstrDefExt=TEXT("txt"); ofn.lpstrTitle=TEXT("名前を付けて保存"); if(!GetSaveFileName(&ofn)) return -1; hFile=CreateFile(szFile,GENERIC_WRITE,0,NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); WriteFile(hFile,buffer,(DWORD)lstrlen(buffer), &dwAccBytes,NULL); SetWindowText(hWnd,szFileTitle); CloseHandle(hFile); return 0; }

  • Visual C++で

    VisualC++を使って、ファイルにint型の二次元配列を書き込みたいのですが、WriteFile関数を使えばよいのかな?というところまではわかったのですが、二番目の引数を"int"型から"LPCVOID"型に変形できませんと言われてしまいます。 雰囲気的には下のような感じになるのかなぁー、と思いましたが、わかりません。教えてください。お願いします。 fp = CreateFile("test.dat", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); for(i = 0; i < 100; i++){ for(j = 0; j < 100; j++){ WriteFile(fp, array[i][j], sizeof(array), &dwRote, NULL); } }

  • フロッピーセクタアクセスに関して

    初めてお目にかかります。 今、PC98で書き込みを行ったフロッピーディスクを読み取るプログラムを作成しています。 インターネットにて調べて見ましたが、うまくいかない状態です。 問題点等あれば教えていただきたいと思います。 実行環境:Windows XP SP2 ドライブ:LOGITEC LFD-31U4 (USB:3モード) 開発言語:VC++(VS2005にて) BOOL Direct_Drive_Access(char *Drive){   HANDLE hHandle;   DISK_GEOMETRY disket;   DWORD dw1;   BOOL ret;   //ハンドルの取得   hHandle = CreateFile(Drive,GENERIC_READ , FILE_SHARE_READ,NULL,OPEN_EXISTING, NULL, NULL);   if ( hHandle != INVALID_HANDLE_VALUE ){     //FDの情報を取得     ret = DeviceIoControl(hHandle,IOCTL_DISK_GET_DRIVE_GEOMETRY,NULL,0,&disket,sizeof(disket),&dw1,NULL);     if (!ret) return FALSE;   } } 上記のソースにて取得したdisketの内容が、1.44MBのフロッピーでした。 (この情報だと、次のReadFile関数で"1785:フォーマットされていません"のエラーが返ります) 実際は、Cylinder - 77 Track - 2 Sector - 26 Byte - 256 でフォーマットしているフロッピーです。 BIOS経由のアクセスも調べましたが、32bitOSのため、使用できない様でした。 これから何を調べていいかも分からない状態なので、アドバイスをお願いします。

専門家に質問してみよう