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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C++

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

Q&A

解決済

2回答

2076閲覧

FormatMessage();関数の引数をどうしたらいいのかわからない。例外がスローされる原因とは。

退会済みユーザー

退会済みユーザー

総合スコア0

C++

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

0グッド

0クリップ

投稿2020/08/27 05:41

編集2020/08/27 06:21

//////////コメント内部のコードですがFormatMessage();の関数の引数の最後の値をどうすればいいいのでしょうか?
一応実装してみましたがなぜか例外がスローされてしまいます。原因がわからず困っているのですがどうすればいいのでしょうか?
公式リファレンスのサンプルコードを見ながら実装しましたがうまくいきません。

質問2、提示コードに警告という行がありますがキャストのコードで[
警告 C6276 意味が異なる文字列型の間でのキャストです: char * から wchar_t * です。無効な文字列を使用すると、未定義の動作を発生させる原因となる可能性があります 。]

環境 Visual studio 2019

公式リファレンス: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessage

#include "stdio.h" #include <iostream> #include <string> #include <Windows.h> void print_pos(char* buf,int pos); void print_pos(char* buf,int pos) { printf("表示: "); for(int i = 0;i <= (pos); i++) { printf("%c",buf[i]); } printf("\n\n\n\n"); } int main() { char buffer[100000]; char* str = nullptr; //const char* wc = "C:\Users\yw325\Desktop\Project1_\x64\Release\test.txt"; const char tt[100] = "test.txt"; const char *de = "\Project_listup.exe"; int tt_s = strlen(tt); int de_s = strlen(de);//.exeファイルの長さ //int bu_s = sizeof(buffer); //printf("size: %d\n",de_s); //今居るディレクトリをパスを取得 printf("今居るディレクトリをパスを取得。\n"); //DWORD e = GetModuleFileNameA(NULL, buffer ,(DWORD)buffer); /// /////////////////////////////////////////////////////////////// DWORD errorLast = GetLastError(); const DWORD size = 200; WCHAR buff[size]; LPWSTR message = (LPWSTR)"ああああ";//警告 va_list *args = nullptr; printf("ああああ\n"); DWORD b = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, (LPCVOID)errorLast,0,0,(LPTSTR)buff,size,args);// //////////////////////////////////////////////////////////// //printf("\nError: %s\n"); }else{ printf("正常です。"); } printf("size: %d\n\n",strlen(buffer));//66文字 //文字列検索して.exeの位置を返す。 printf("文字列検索して.exeの位置を返す。\n"); int s = strlen(buffer); char* _buffer = strstr(buffer,de);//_bufferに.exeの位置を示している int now = s - de_s;//.exeまでの文字数 printf("%s\n",_buffer); printf("パスの全体 - .exeの位置 size: %d\n",now); int i = 0; for(int i = now; i > 0; i--) { --_buffer; } print_pos(_buffer,47); while(_buffer[i] == '\0') { ++_buffer; i++; } print_pos(_buffer,66); size_t size = sizeof(buffer) + sizeof(de); //strcat_s(_buffer,size,de); printf("ファイル名を追加\n\n\n\n\n\n"); printf("%s\n",_buffer); if(buffer == nullptr){ printf("nullptr"); } // printf("%s\n",buffer); int _c_ = getchar(); return 0; }

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

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

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

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

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

dodox86

2020/08/27 05:46

質問文中に挙げた公式リファレンスの説明中に、使用例、サンプルコードが載っていますが、何が分からないのでしょうか。
退会済みユーザー

退会済みユーザー

2020/08/27 05:53 編集

失礼しました。最後までリファレンスを見ていませんでした、すいませんでした。 質問ですがGetModuleFileNameA();が返すエラーコードはhttps://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulefilenameaにもある通りERROR_INSUFFICIENT_BUFFERでよろしいのでしょうか?下の行にもにたような#defineと思われるコードが多いので気になりました。
guest

回答2

0

ベストアンサー

といった感じで実装できました。自己解決です。ワイド文字とマルチバイト文字の違いを学習したしだいです

DWORD e = ERROR_INSUFFICIENT_BUFFER; if(e == ERROR_INSUFFICIENT_BUFFER) { DWORD errorLast = GetLastError(); DWORD size[200]={ }; LPWSTR source = NULL; char buff[200]; va_list *args = nullptr; printf("ああああ\n"); DWORD b = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, source, errorLast, LANG_USER_DEFAULT, buff, (DWORD)sizeof(size), args); printf("\nError: %s\n",buff); getchar(); exit(1); }else{ printf("正常です。"); }

投稿2020/08/27 08:56

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

guest

0

c++

1GetModuleFileNameA(NULL, buffer ,sizeof(buffer)); 2DWORD last_error = GetLastError(); 3if(last_error != ERROR_SUCCESS) 4{ 5 LPSTR msg; 6 FormatMessageA( 7 FORMAT_MESSAGE_ALLOCATE_BUFFER | 8 FORMAT_MESSAGE_FROM_SYSTEM | 9 FORMAT_MESSAGE_IGNORE_INSERTS, 10 NULL, 11 last_error, 12 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 13 (LPSTR) &msg, 14 0, NULL ); 15 puts(msg); 16 LocalFree(msg); 17} else { 18 puts(buffer); 19}

こんな感じ


FORMAT_MESSAGE_ALLOCATE_BUFFERを使わない場合

c++

1 CHAR msg[1000]; 2 if(FormatMessageA( 3 FORMAT_MESSAGE_FROM_SYSTEM | 4 FORMAT_MESSAGE_IGNORE_INSERTS, 5 NULL, 6 last_error, 7 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 8 msg, 9 sizeof(msg), NULL )) puts(msg); 10 else 11 puts("エラーメッセージの取得に失敗しました。");

投稿2020/08/27 06:59

編集2020/08/27 08:31
asm

総合スコア15147

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

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

退会済みユーザー

退会済みユーザー

2020/08/27 07:04

ありがとうございます。自分は DWORD e = ERROR_INSUFFICIENT_BUFFER; if(e == ERROR_INSUFFICIENT_BUFFER) { DWORD errorLast = GetLastError(); const DWORD size = 200; WCHAR buff[size]; LPCVOID message = &errorLast; va_list *args = nullptr; printf("ああああ\n"); DWORD b = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_IGNORE_INSERTS, message,0,0,(LPTSTR)buff,size,args);// 実装してみたのですが違うのでしょうか?
asm

2020/08/27 07:17

> DWORD errorLast = GetLastError(); たぶん何かapi呼び出して失敗しないとERROR_SUCCESS=0が返ってきます。 > LPCVOID message = &errorLast; 意味不明 > FORMAT_MESSAGE_FROM_STRING エラーコードを文字列化する際は FORMAT_MESSAGE_FROM_SYSTEMを使うこと
退会済みユーザー

退会済みユーザー

2020/08/27 07:55 編集

質問ですが エラーコードを文字列化についてですが文字化けということでしょうか? また実装できましたがこれはどいう意味なのでしょうか? 「この操作を正しく終了しました。」 エラーが発生しているににも関わらずどうしてこうなるのでしょう?
asm

2020/08/27 08:09

> 質問ですが エラーコードを文字列化についてですが文字化けということでしょうか? 何が言いたいのか分かりませんが、文字化けとは関係ありません。 > 「この操作を正しく終了しました。」 再度言いますが > DWORD errorLast = GetLastError(); たぶん何かapi呼び出して失敗しないとERROR_SUCCESS=0が返ってきます。
退会済みユーザー

退会済みユーザー

2020/08/27 08:57

Windows.h をインクルードして関数を使っているのでもうすでにapiが入っているのでしょうか?
asm

2020/08/27 09:40

プロセス起動時にSetLastError(0)がコールされているとみなしてもほぼ問題ないでしょう。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問