C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[7]: 標準出力先を外部プログラムにしたい


(過去ログ 117 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■68934 / inTopicNo.1)  標準出力先を外部プログラムにしたい
  
□投稿者/ たそ (1回)-(2013/11/25(Mon) 22:06:58)

分類:[C#] 

はじめまして、たそといいます。

Cのコンソールアプリケーション(プログラムA)とC#のコンソールアプリケーション(プログラムB)の
2つのプログラム間で文字列のやりとりを行うプログラムを作ろうと考えています。

開発環境:VS2010
使用言語:C, C#(バージョンに制限はありません)

[プログラムA:C言語]
#include <stdio.h>
int main(){
 char buf[1024];
 scanf("%s", buf);
 printf("program a : %s", buf);
 return 0;
}

このプログラムAの標準入力に対して、C#のプログラムBが入力を行う
というものを作成したいと考えております。

プログラムBの標準出力先をプログラムAにするような方法があれば教えて頂きたく書き込ませて頂きました。
また、プログラムA側でプログラムBの標準出力を得る、リダイレクションのようなことしない解決方法でおねがいします。

どうかよろしくお願いいたします。

引用返信 編集キー/
■68942 / inTopicNo.2)  Re[1]: 標準出力先を外部プログラムにしたい
□投稿者/ 魔界の仮面弁士 (428回)-(2013/11/25(Mon) 23:20:32)
No68934 (たそ さん) に返信
> このプログラムAの標準入力に対して、C#のプログラムBが入力を行う
> というものを作成したいと考えております。
すなわち、
・A は既存のコンソールアプリ。B はこれからC#で作成するアプリ。
・A の標準入力に、B からデータを渡したい。
ということですね。
であれば、Process.StandardInput プロパティが使えるのではないでしょうか。


> プログラムBの標準出力先をプログラムAにするような方法があれば教えて頂きたく書き込ませて頂きました。
B の標準出力を A で読み取りたい、ということでしょうか。
やりたいことは、A の標準入力へ B から書き込むことだったのでは?

タイトルには「標準出力先を外部プログラムにしたい」とありますから、実際の質問は
・A は既存のコンソールアプリ。B はこれから作成するアプリ。
・A の標準出力を、B で読み取りたい。
ということなのでしょうか。であれば、Process.StandardOutput プロパティが使えるかと思います。
http://dobon.net/vb/dotnet/process/standardoutput.html


両方やりたいという話だとしたら、Process クラスで A を起動するようにし、
その Process の StandardInput / StandardOutput の双方を、C# にて操作するような
つくりにすれば良いと思います。


> プログラムA側でプログラムBの標準出力を得る、リダイレクションのようなことしない
話を聞く限り、B の標準入出力に手を加える必要は無いように思えます。
引用返信 編集キー/
■68956 / inTopicNo.3)  Re[2]: 標準出力先を外部プログラムにしたい
□投稿者/ たそ (3回)-(2013/11/26(Tue) 14:35:45)
No68942 (魔界の仮面弁士 さん) に返信

魔界の仮面弁士さん丁寧な解説ありがとうございました!!

目的の動作が、返信頂いた「両方やりたい」の内容だったので
StandardInput / StandardOutputの双方をC#で操作することで作成することができました。


昨日質問させて頂いた処理は完成したのですが、
これを応用しようと思ったところで手詰まりになってしまったので、
もしよければ以下の処理の解決方法にもアイディアを頂きたく思います・・・(すいません...



<改善したい内容>
「Aの出力結果が非同期の出力を行ってもリアルタイムに表示されない。」

<目標の実行結果>
input:hoge
client : hoge
input:hogehoge
client : hogehoge
input : ^Z


<現在の実行結果>
input:hoge
input:hogehoge
input:^Z
client : hoge
client : hogehoge



[プログラムA:C言語]

int main(){
	char buf[1024];
	while( scanf("%s", buf) != EOF){
		printf("client : %s\n", buf);
	}
	return 0;
}


[プログラムB:C#]

class Program
{
	static void Main(string[] args)
	{
		System.Diagnostics.Process myProcess = new System.Diagnostics.Process();
		myProcess.StartInfo.FileName = "プログラムA.exe";
		myProcess.StartInfo.UseShellExecute = false;
		myProcess.StartInfo.RedirectStandardInput = true;
		myProcess.StartInfo.RedirectStandardOutput = true;
		myProcess.OutputDataReceived += p_OutputDataReceived;
		myProcess.Start();
		myProcess.BeginOutputReadLine();
			System.IO.StreamWriter myStreamWriter = myProcess.StandardInput;
			String inputText;
		do {
			Console.Write("input:");
			inputText = Console.ReadLine();
			myStreamWriter.WriteLine(inputText);
		} while(inputText != null);
			myStreamWriter.Close();
		myProcess.WaitForExit();
		myProcess.Close();
		}
	
	static void p_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
	{
		Console.WriteLine(e.Data);
	}
}


また、以上のプログラムBにブレークポイントを置いて確認したところ
myStreamWriter.Close()後にp_OutputDataReceived()が呼び出されてるため、
myStreamWriter.WriteLine()と書いてもすぐにプログラムAに引数の内容が送られる仕様ではないのかな?と思ったり…。
もし、このような仕様なのであれば、非同期的にProcess.StandardInputのストリームに書き込む方法を知りたく思います。

引用返信 編集キー/
■68957 / inTopicNo.4)  Re[3]: 標準出力先を外部プログラムにしたい
□投稿者/ 774RR (123回)-(2013/11/26(Tue) 15:43:22)
C の scanf や printf は自前でバッファリングする機能を持っている
C# の StreamWriter は自前でバッファリングする機能を持っている

ので、そういうリアルタイムな要望には向いていない。
(バッファリングしない=負荷が不必要に重いってことで、標準ではバッファあり)

出力側としては StreamWriter の AutoFlush を調べてみよう。
入力側としては setvbuf を調べてみよう。

# 今回の案件ではスペース文字の扱いなどの面で scanf 使うこと自体が間違っているのでは・・・
引用返信 編集キー/
■68963 / inTopicNo.5)  Re[4]: 標準出力先を外部プログラムにしたい
□投稿者/ たそ (4回)-(2013/11/26(Tue) 18:47:44)
No68957 (774RR さん) に返信
> C の scanf や printf は自前でバッファリングする機能を持っている
> C# の StreamWriter は自前でバッファリングする機能を持っている
>
> ので、そういうリアルタイムな要望には向いていない。
> (バッファリングしない=負荷が不必要に重いってことで、標準ではバッファあり)
>
> 出力側としては StreamWriter の AutoFlush を調べてみよう。
> 入力側としては setvbuf を調べてみよう。

774RRさん、アドバイスありがとうございました!
標準入出力関数のバッファリング機能のこと、ストリームのflushなどについて調べた結果、
出力画面を持たないAのprintfが原因だということがわかりました、

そして、[プログラムA]を以下のように変える事で目標の実行結果を得ることができました。

int main(){
char buf[1024];
while(scanf("%s",buf) != EOF){
printf("client : %s\n", buf);
fflush(stdout);
}
return 0;
}

中の動きを理解できていない初心者にアドバイスしてくださった
魔界の仮面弁士さん、774RRさん本当にありがとうございましたm(_ _)m
解決済み
引用返信 編集キー/
■68970 / inTopicNo.6)  Re[5]: 標準出力先を外部プログラムにしたい
□投稿者/ Jitta (112回)-(2013/11/26(Tue) 21:17:19)
Jitta さんの Web サイト
No68963 (たそ さん) に返信

水を差して申し訳ないですが、

> プログラムA側でプログラムBの標準出力を得る、リダイレクションのようなことしない解決方法

を満足していませんが、良いのですか?
解決済み
引用返信 編集キー/
■68973 / inTopicNo.7)  Re[6]: 標準出力先を外部プログラムにしたい
□投稿者/ 魔界の仮面弁士 (434回)-(2013/11/26(Tue) 22:03:19)
No68970 (Jitta さん) に返信
>>プログラムA側でプログラムBの標準出力を得る、リダイレクションのようなことしない解決方法
> を満足していませんが、良いのですか?

No68956 を見る限り、C# 側が文字列を送出しているのは、
B自身への Console.Out.WriteLine (B の標準出力への書き込み)ではなく、
Aプロセス.StandardInput.WriteLine (A の標準入力への書き込み)なので、
「B の標準出力」を A 側が得ていることにはならないのでは無いでしょうか。
(捉え方の問題かもしれませんが…)
解決済み
引用返信 編集キー/
■69029 / inTopicNo.8)  Re[7]: 標準出力先を外部プログラムにしたい
□投稿者/ Jitta (115回)-(2013/11/28(Thu) 21:14:54)
Jitta さんの Web サイト
No68973 (魔界の仮面弁士 さん) に返信
> No68956 を見る限り、C# 側が文字列を送出しているのは、
> B自身への Console.Out.WriteLine (B の標準出力への書き込み)ではなく、
> Aプロセス.StandardInput.WriteLine (A の標準入力への書き込み)なので、
> 「B の標準出力」を A 側が得ていることにはならないのでは無いでしょうか。
> (捉え方の問題かもしれませんが…)

 まず、ごめんなさい、魔界の仮面弁士さんの回答が間違いというつもりは、全くありません。
最初に、「プログラムA側でプログラムBの標準出力を得る、リダイレクションのようなことしない」
と書かれていました。これが、何を意図しているのか分からない、というのが、メインです。

 また、「同期」「非同期」の言葉の使い方も気になっています。

> 「Aの出力結果が非同期の出力を行ってもリアルタイムに表示されない。」

No 68956 のコードでは、標準出力に、WriteLine メソッドを使って同期出力しています。
それなのに、「非同期の出力を行っても」という言葉を使われています。
それとも、WriteAsync メソッドに変えてみた、ということなのでしょうか。

 この2つから、用語の使い方が間違っていると思います。
そこで、質問者さんに、「尋ねたいことを正確に伝えているか」
というところを確認していただきたいと思います。


 もう一つ付け加えると、

> プログラムAの標準入力に対して、C#のプログラムBが入力を行う

について、私は、AとBは別々に起動されるのだと思っていました。
どのようなアプリケーションを作りたいのか、分かりません。

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -