趣味で C/C++ ( Windows API 実装 ) でやっています。
コマンドライン引数を取得して処理することに関してです。
「C言語 入門」, 「C++ 入門」で検索すると
"コマンドライン引数" の項目 があったりします。
これに関しては問題ないのですが、CUI, GUIどちらでも使えるようにしたいので、
クラス化 ( or 関数化 ) したいと思っています。
CUIの場合は、 main関数の int argc, char **argv で比較的簡単に取得できます。
GUI ( Windows API でやる場合 ) の場合は PTSTR でしたっけ?
それに入っているようですが、
$main abc -a -b -f file1.txt
と打つと、
"main abc -a -b -f file1.txt" で一つとなるので、
これを編集するのが大変です。
なので Google 「C言語 Windows API コマンドライン引数」みたいに検索したところ、
「山内の授業補完のページ/Windowsアプリ/argcとargv - 東邦大学理学部情報科学科 山内のサイト」
がヒットしました。
こちらのサイトのソースコードを拝借してクラス化して... とやってみました。
一応うまくいったのですが、ある条件のときがおかしくなります。
"ある条件"というのは よくわかっていませんが、場合によっては何故かコマンドライン引数が 途中で切れるというか、文字化けするというか、
なんかわけわからないことになります。
そのときのデータを比較してみると 「日本語が含まれている」 といった感じです。
(実行ファイルの)ファイルパス とか コマンドライン引数として 日本語で 渡すとか。
例:
$main -f "C:\やっほー\file1.txt" -d "このデータが追加されればOK"
rem これを cout とか MessageBoxとかで見ると
rem main -f "C:\やっほー\・" -d "・。:・・"
rem みたいになっている。
rem ※ 結果は例です。
ソースコード:
(字数制限のため、他のサイトを利用しています。)
https://pastebin.com/J5Sy7ECh
呼び出し側は
C++
1 2CCommandLine* CmdLine = new CCommandLine(); 3 4for( int i = 0; i < CmdLine->Size(); i++ ){ 5 // CmdLine->At( i ) を表示 6} 7 8delete CmdLine;
のようにしています。
ですが、なぜか文字化けというか、途中で途切れるというか...
うまくいきません。
階層を変更して、 Cドライブ直下とかのように 日本語が入らないようにすると普通に ( ファイルパスの方は ) うまくいきます。
これってどういう理由なのでしょうか?
一応、コード上では wstring -> string と変更する関数があります。
char型配列と wchar_t型配列 で入れたときの大きさ ( 要素数 ) が違うので、
w -> s にするときには 2倍にしてみました。
ですが、それでも同じ...
GUI の場合は (実行ファイルとコマンドライン引数が) 一つになっているので
自分で分解する関数を作るのもいいですが、
やり方がわかりません。
strtok関数等で分解する分にはいいですが、区切り方が...
基本的に 半角スペースで区切られているので
区切り文字 = 半角スペース
とみなすこともできますが、
"abc test"
という風に 半角スペースが "文字" として出現している場合もあります。
他の文字を当てる... これも方法としてはアリですが、
ユーザからすると「わからない」ので、ボツ。
上記コードを w -> c に変換せずに使う方法もありますが、
これだとちょっと厳しい...
CUIだと使えないことが多い ( ほとんどの関数は char型配列を想定している ) ので、NG。
しかも GUIだとしても C/C++本来の関数やクラスを使う場合も同様。
なので どうしても w -> c としないといけません。
どういう風に考えれば宜しいのでしょうか...
ご存じの方、解決法( へのヒント ) を宜しくお願い致します。
[情報]
言語 : C/C++
WinAPI : あり
コンパイラ: MinGW ( g++ )
回答3件
あなたの回答
tips
プレビュー