質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
ファイルI/O

ファイルI/Oは、コンピューターにおけるファイルの入出力です。これは生成/削除やファイルを読み込んだり、出力をファイルに書き込むようなディレクトリやファイルの運用を含みます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

1065閲覧

C++:ファイル出力

退会済みユーザー

退会済みユーザー

総合スコア0

ファイルI/O

ファイルI/Oは、コンピューターにおけるファイルの入出力です。これは生成/削除やファイルを読み込んだり、出力をファイルに書き込むようなディレクトリやファイルの運用を含みます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/09/29 23:28

わからないこと

_tprintfを使用して出力している内容を、WriteFile関数を使用してファイルに出力したいと考えています。
WriteFile関数は以下のように使用することは分かっています。つまり第2引数に_tprintf()の括弧内部の情報を入れたいということです。
しかしどのようにすれば実現できるかわからず、質問させていただいております。
宜しくお願い申し上げます。

WriteFile関数の仕様

function WriteFile(
hPort: THandle;
const lpBuffer;
NumberOfBytesToWrite: DWORD;
var lpNumberOfBytesWritten: DWORD;
lpOverlapped: POverlapped
): Thandle; stdcall;

実行環境

言語:C++
開発環境:Visual Studio 2017

ソースコード

CString strDevName; _tprintf(L"%ls%ls%ls", L"サーバ名'", strDevName, L"'を設定しました。\n");

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

第一引数にファイルハンドル、
第二引数に書き込みデータのバッファアドレス、
第三引数は書き込みバイト数、
第四引数は書き込みバイト数を返す変数
第五引数はオーバーラップ構造体のアドレス、
を渡して呼び出せばいいです。

投稿2019/09/29 23:54

編集2019/09/30 01:43
y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/09/30 00:03

_tprintf()のバッファアドレスが理解できていません。 私の認識では_tprintf()の括弧内のアドレスをWriteFileの第二引数に渡してあげれば良いと考えています。 今回のケースではそれはどのようにしたらわかりますか?教えて頂くことは可能でしょうか?
dodox86

2019/09/30 00:09

ちなみに、第4引数は「書き込んだバイト数を格納する変数へのアドレス」です。 オーバーラップ構造体のアドレスは第5引数です。間違っています。
y_waiwai

2019/09/30 00:09

書き込むデータを格納している場所のアドレス、ってことです。 printfでは出力結果はコンソールに出されますが、これをsprintfを使えば文字列バッファに結果を展開できます。それを使いましょう
y_waiwai

2019/09/30 00:12

ああ、第四引数は書き込んだバイト数ですね みおとしてました >dodox86
退会済みユーザー

退会済みユーザー

2019/09/30 00:23

「書き込むデータを格納している場所のアドレス」をscanfで取得できるということですか?できれば、私の質問内容を例に具体的な方法を教えていだだけますでしょうか?
退会済みユーザー

退会済みユーザー

2019/09/30 00:23

>dodox86様 第4引数は「書き込んだバイト数を格納する変数へのアドレス」ですね。ありがとうございます。
y_waiwai

2019/09/30 00:33

scanf では、あらかじめ確保しておいた文字配列に、出力結果を格納することができる、です。 sprintf でぐぐって、使い方を調べてみてください
退会済みユーザー

退会済みユーザー

2019/09/30 01:41

sprintfで配列にアドレスを取得し、ファイルに書き込みできました。ありがとうございます。
y_waiwai

2019/09/30 01:44

BAになってしまった(?)ので、ややこしいので回答を修正しておきます。。
dodox86

2019/09/30 02:01

y_waiwaiさんの回答で必要充分だったですね。(私の回答は冗長/余計なお世話過ぎた)
guest

0

どのようなプログラム要求仕様があったかは分かりませんが、本来、Win32APIであるWriteFileを使うまでもないです。WriteFileを使いたいのであれば、ファイルオープンにはCreateFileを使わなければならないし、Windows特有のAPIなので、比較的初心者の方にはあまりお勧めできないものでもあります。それでも質問に回答するならば、以下のようなコードになるかと思います。

C++

1#include <Windows.h> 2#include <locale.h> 3#include <atlstr.h> // CString 4#include <stdio.h> 5 6int main() 7{ 8 setlocale(LC_ALL, "Japanese"); 9 10 CString strDevName = _T("DeviceName"); 11 12 // _t...関数群を使うなら、_Tマクロを使うべきでは。 13 // _tprintf(L"%ls%ls%ls", L"サーバ名'", strDevName, L"'を設定しました。\n"); 14 _tprintf(_T("%ls%ls%ls"), _T("サーバ名'"), (LPCTSTR)strDevName, _T("'を設定しました。\n")); 15 16 // 書きたいデータはいったんバッファーに格納しとく 17 TCHAR message[256]; 18 _stprintf_s(message, _countof(message), _T("%ls%ls%ls"), _T("サーバ名'"), (LPCTSTR)strDevName, _T("'を設定しました。\n")); 19 _tprintf(_T("%s"), message); 20 21 // WriteFileを使う版 22 const TCHAR fileName[] = _T("./output.txt"); 23 HANDLE handle = CreateFile(fileName, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 24 if (handle != INVALID_HANDLE_VALUE) { 25 DWORD numOfBytesWritten = 0; 26 BOOL succeeded = WriteFile( 27 handle, // ファイルハンドル 28 message, // 書き込みたいデータのアドレス 29 _tcslen(message) * sizeof(message[0]), // 書き込みたいデータの"バイト"数 30 &numOfBytesWritten, // 書き込みが成功した場合に実際に書き込んだバイト数を格納する変数へのポインタ 31 NULL); // WriteFile API を非同期で使う場合のみセットする。使わないのでNULLで可 32 if (succeeded) { 33 _tprintf(_T("%lu バイト書き込みました。\n"), numOfBytesWritten); 34 } 35 else { 36 DWORD lastError = GetLastError(); 37 _tprintf(_T("ファイル書き込みに失敗しました。GetLastError()=%lu, 0x%X\n"), lastError, lastError); 38 39 } 40 CloseHandle(handle); 41 } 42 43 // Win32 APIを使うまでもないかと。標準入出力のライブラリで充分かつ使いやすい 44 FILE* fp; 45 errno_t err = _tfopen_s(&fp, fileName, _T("ab")); 46 if (err == 0) { 47 48 _tprintf(_T("%s"), message); 49 50 // _tprintfと同じ,標準出力へ出力 51 _ftprintf(stdout, _T("%s"), message); 52 53 // ファイル(fp)へ出力 54 _ftprintf(fp, _T("%s"), message); 55 fclose(fp); 56 } 57 58 return 0; 59}

ご質問のコードではCStringが出てきたり、_tprintfに対してWriteFileであったり、間違いではありませんが、若干混乱が見受けられます。WriteFileではなく、fopenfwrite, fprintf等の標準関数でもファイルは十分扱えるので、まずはそれらでやってみるのも良いかと思います。上記サンプルコードでは_tfopen, _ftprintfで同じようなコードを追記しています。

尚、出力されるファイルのエンコードには注意してください。UNICODEビルドですとUTF16LEになります。

投稿2019/09/30 00:37

編集2019/09/30 00:42
dodox86

総合スコア9183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問