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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Windows 7

Microsoft Windows 7は過去にリリースされたMicrosoft WindowsのOSであり、Windows8の1代前です。2009年の7月にリリースされ販売されました。Windows7の前はWindowsVistaで、その更に3年前にリリースされました。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

コマンドプロンプト

コマンドプロンプト(cmd.exe)はMicrosoftによって提供されているコマンドラインインタプリタです。OS/2・Windows CE・Windows NTで使用可能です。

バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

Q&A

解決済

3回答

7645閲覧

batファイル内で、スペースを含む引数をCプログラムに渡す場合の処理

minato_hy

総合スコア68

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Windows 7

Microsoft Windows 7は過去にリリースされたMicrosoft WindowsのOSであり、Windows8の1代前です。2009年の7月にリリースされ販売されました。Windows7の前はWindowsVistaで、その更に3年前にリリースされました。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

コマンドプロンプト

コマンドプロンプト(cmd.exe)はMicrosoftによって提供されているコマンドラインインタプリタです。OS/2・Windows CE・Windows NTで使用可能です。

バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

0グッド

1クリップ

投稿2017/06/20 13:41

編集2022/01/12 10:55

###前提・実現したいこと
受け取ったコマンドライン引数を列挙するCプログラムがあり、batファイル内でそのCプログラムに引数を渡し実行したいのですが、引数にスペースが含まれる場合の処理に困っています。

###発生している問題・エラーメッセージ
[1] スペースを含むパスを変数に格納し、Cプログラムにその変数を引数として渡した場合、そのまま渡すとスペースの部分で変数の中身が分割されてしまいます。

[2] しかし変数を渡すときにダブルクォーテーションで囲むと、なぜかその変数以降の引数まで合わせてひとつの引数と認識されてしまいます。

なにか解決方法はありますでしょうか。

[1]の場合の結果 0: a 1: C:\test 2: files\ 3: 2 4: 3 [2]の場合の結果 0: a 1: C:\test files\ 2 3

###該当のソースコード
batファイルの場所:C:\test files\

a.exe

C

1#include<stdio.h> 2int main(int argc, char *argv[]){ 3 int i; 4 for(i=0; i<argc; i++){ 5 printf("%d: %s\n", i, argv[i]); 6 } 7 return 0; 8}

test.bat

bat

1@echo off 2rem 3set path=%~dp0 // カレントディレクトリのパス(スペースが含まれる) 4a.exe %path% 2 3 // [1]の場合 5a.exe "%path%" 2 3 // [2]の場合

###補足情報(言語/FW/ツール等のバージョンなど)
windows7
gcc

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

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

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

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

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

guest

回答3

0

ベストアンサー

2つ目の"が、直前に\があるためにエスケープされた状態になっています。
\\と重ねると、gccだと上手く行きます。bccは駄目ですね。Cに依存するようです。

あと、PATHという環境変数名は特別な意味を持っていますので、他の目的には使わない方が良いです。

DOS

1set A=%~dp0 2a.exe "%A%\" 2 3

#追記
上記で駄目な場合、
案1.%A%の後に何か文字(空白とか)を付け加えてプログラムに渡し、プログラムでそれを取り除く
案2.%A%の末尾の\を取り除いてからプログらに渡し、プログラムで\を付加する
くらいでしょうか。

投稿2017/06/20 14:42

編集2017/06/20 22:00
otn

総合スコア84423

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

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

minato_hy

2017/06/21 11:36

なるほど、変数内の末尾の \ は気付きませんでした。gccで試してみたところ末尾に余計な \ が付いてしまいますが、Cプログラム側の処理でなんとかなりそうです。 なおPATHについては説明の解りやすさのために投稿時のみこの変数名にしております。とはいえご忠告感謝です。
otn

2017/06/21 14:45

> 投稿時のみこの変数名にしております であれば、PATHNAMEとかが良かったですね。
guest

0

otnさんのコメントから「WindowsではexecutableのCランタイムにより引数の解釈が変わる」という点がようやく実感できた気がします。以下の回答の前提はcygwin64上のgcc 6.3.0で作成したexecutableです。あまり一般的とはいえないかもですね。

to:質問者さん
どのコンパイラー(どのCランタイム)かにより違うということだと思います。それを明確にしたほうがよさそうですね。


set path=%~dp // カレントディレクトリのパス(スペースが含まれる)

バッチファイルに%~dpと書いてやってみたのですがパス演算子が間違って使われてますというエラーになり、どうやったらこの記述が動くのか自分にはわかりませんでした。そこでバッチファイルが存在するディレクトリーなのだろうと解釈し%~dp0に置き換えてやってみました。(Windows10 64bit)

で、内容がバックスラッシュで終わっている変数を一つの引数として渡す場合、ダブルクォート文字ではなくシングルクォート文字で囲むといいみたいです。

a.exe '%変数名%' arg2 arg3 ...

ただotnさんのコメントを拝見すると、この方法が正しいかどうか少々自身ないです。コンパイラーのランタイムによってコマンドの引数の解釈が変わってくる(!)ということがどういう理屈か自分に分かっていないからです。自分はcygwin64のgccでa.exeを作成し、それをコマンドプロンプト上で動かすという少々ヘンテコなことをしています。

投稿2017/06/21 00:25

編集2017/06/21 08:53
KSwordOfHaste

総合スコア18392

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

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

otn

2017/06/21 08:12

私は、mingw の gcc ですが、cygwinとは仕様が違うようですね。mingwだとシングルクォートは特殊文字じゃ無いようです。
KSwordOfHaste

2017/06/21 08:40 編集

自分は知らず知らずのうちにargc, argvを決める引数の分離がWindowsでも呼び出し側で決まるというふうに思い込んでいました。CreateProcessのリファレンスをみたら「引数を並べた単一の文字列が第二引数になっているだけ」ということに今更ながら気づいて愕然としました・・・ Win32 APIを使ったことがないとはいえ、ちょっと恥ずかしい勘違いです。 otnさんの回答とコメントで勉強させていただきました。大変ありがとうございました。
minato_hy

2017/06/21 11:47

私もcygwin上のgccでコンパイルしコマンドプロンプト上で実行するので、シングルクォーテーションで上手くいきそうです。色々検索してもシングルクォーテーションについては調べられなかったので助かりました。後ほど試してみて、成功すればいったんこの質問は閉じさせていただきます。
minato_hy

2017/06/21 11:49

あとコメントに入れ忘れましたが%~dpはご指摘の通りバッチファイルのディレクトリを取得する%~dp0のミスです。質問文修正しました。
guest

0

うまくいくかわかりませんが、スペースを含むひとかたまりの値をシングルクォーテーションでくくっておいて、それらをダブルクォーテーションでくくって渡してあげたらどうなりますか?

投稿2017/06/20 18:36

dojikko

総合スコア3939

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

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

minato_hy

2017/06/21 11:39

"'%PATH%'"で試してみると、'C:\test files\'とシングルクォーテーションで囲まれてはいましたがちゃんと引数ごとに表示されていました。ちなみに、'"%PATH%"'というように内側をダブルクォーテーションにしたところ、"C:\test files\"のように表示されました。なるほど
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問