<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[iostream ableiten -&amp;gt; werden &#x5C;n gelöscht?]]></title><description><![CDATA[<p>Hallo,<br />
ich bin dabei ne Klasse zu schreiben, die ein externes programm startet (in nem geforkten prozess) und pipes dahin legt. Die Pipes will ich benutzbar machen indem ich die klasse von streambuf ableite und ein iostream derivat daran anbinde... (wenn die klasse fertig ist, will ich sie unter GPL3 veröffentlichen)<br />
an sich bin ich schon ziemlich weit, aber irgendwie scheinen die daten nicht mehr durch die pipes zu gehen, seit die klasse von streambuf abgeleitet ist...<br />
also ich schicke einen string in den stream rein, kriege dann aber nicht die erwartete antwort raus...<br />
ich bin nicht sicher, aber ich glaube, das problem liegt zwischen dem aufruf des &lt;&lt; operators und xsputn. wenn ich bla\n\n in den stream schicke, kommt bla\0 bei xsputn an und <em>n</em> ist 3 (ich denke das soll heissen, dass bis s[n] gelesen werden soll - etwas unüblich, aber ok)<br />
jedenfalls erwartet das externe programm ein \n, bis es antwortet (ich benutze testweise cat, das einfach die eingabe wieder zurückgeben müsste - aber auch mit nem anderen prog funktioniert es nicht...)</p>
<p>testweise habe ich in der overflow methode mal explizit *_M_out_cur auf \n gesetzt und *(_M_out_cur+1) auf \0 (um sicherzugehen), aber es kam immernoch nicht die erwartete antwort...</p>
<p>sieht vielleicht jemand einen fehler in den folgenden methoden?</p>
<pre><code class="language-cpp">streamsize exec_streambuf::xsputn(const char* s, streamsize n) {
	if(_M_out_cur+n &lt;= _M_out_end) { // request can be satisfied
		memcpy(_M_out_cur, s, sizeof(char_type)*n);
		_M_out_cur += n+1;
		return 1;
	}

	// not enough space - fill rest
	int availspace = _M_out_end - _M_out_cur;
	if(availspace &gt; 0) {
		memcpy(_M_out_cur, s, sizeof(char_type)*availspace);
		_M_out_cur = _M_out_end;
	}

	// flush and redo
	if(overflow(s[availspace]) != traits_type::eof()) {
		return xsputn(s+availspace, n-availspace);
	} else
		return traits_type::eof();
}

exec_streambuf::int_type exec_streambuf::overflow(int_type c) {
	*_M_out_cur = '\0'; // flush buffer
	if(fwrite(_M_out_beg, sizeof(char_type), 1+_M_out_cur-_M_out_beg, PipeWriter) &gt; 0) {
		fflush(PipeWriter);

		_M_out_cur = _M_out_beg+1; // reset buffer
		*_M_out_beg = c;
		return 1;
	} else {
		return traits_type::eof();
	}
}
</code></pre>
<p>ach, es könnte vielleich helfen, den aufruf aus der main zu haben</p>
<pre><code class="language-cpp">execstream P(argv[1]);
char input[256];
string output;
while(true) {
	cin.getline(&amp;input[0],256);
	P &lt;&lt; input &lt;&lt; &quot;\n\n&quot;;
	P.flush();
	P &gt;&gt; output;
	cout &lt;&lt; output &lt;&lt; endl;
}
</code></pre>
<p>wer's mal testen will:<br />
<a href="http://www.algorithman.de/storage/ExecStream.h" rel="nofollow">http://www.algorithman.de/storage/ExecStream.h</a><br />
<a href="http://www.algorithman.de/storage/test.cpp" rel="nofollow">http://www.algorithman.de/storage/test.cpp</a></p>
<p>(funktioniert afaik nicht unter windows - weil das afaik den fork nicht unterstützt)<br />
danke!</p>
<p>AlgoMan</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/238708/iostream-ableiten-gt-werden-n-gelöscht</link><generator>RSS for Node</generator><lastBuildDate>Tue, 22 Sep 2026 22:33:06 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/238708.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 14 Apr 2009 15:34:26 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to iostream ableiten -&amp;gt; werden &#x5C;n gelöscht? on Tue, 14 Apr 2009 16:02:13 GMT]]></title><description><![CDATA[<p>Hallo,<br />
ich bin dabei ne Klasse zu schreiben, die ein externes programm startet (in nem geforkten prozess) und pipes dahin legt. Die Pipes will ich benutzbar machen indem ich die klasse von streambuf ableite und ein iostream derivat daran anbinde... (wenn die klasse fertig ist, will ich sie unter GPL3 veröffentlichen)<br />
an sich bin ich schon ziemlich weit, aber irgendwie scheinen die daten nicht mehr durch die pipes zu gehen, seit die klasse von streambuf abgeleitet ist...<br />
also ich schicke einen string in den stream rein, kriege dann aber nicht die erwartete antwort raus...<br />
ich bin nicht sicher, aber ich glaube, das problem liegt zwischen dem aufruf des &lt;&lt; operators und xsputn. wenn ich bla\n\n in den stream schicke, kommt bla\0 bei xsputn an und <em>n</em> ist 3 (ich denke das soll heissen, dass bis s[n] gelesen werden soll - etwas unüblich, aber ok)<br />
jedenfalls erwartet das externe programm ein \n, bis es antwortet (ich benutze testweise cat, das einfach die eingabe wieder zurückgeben müsste - aber auch mit nem anderen prog funktioniert es nicht...)</p>
<p>testweise habe ich in der overflow methode mal explizit *_M_out_cur auf \n gesetzt und *(_M_out_cur+1) auf \0 (um sicherzugehen), aber es kam immernoch nicht die erwartete antwort...</p>
<p>sieht vielleicht jemand einen fehler in den folgenden methoden?</p>
<pre><code class="language-cpp">streamsize exec_streambuf::xsputn(const char* s, streamsize n) {
	if(_M_out_cur+n &lt;= _M_out_end) { // request can be satisfied
		memcpy(_M_out_cur, s, sizeof(char_type)*n);
		_M_out_cur += n+1;
		return 1;
	}

	// not enough space - fill rest
	int availspace = _M_out_end - _M_out_cur;
	if(availspace &gt; 0) {
		memcpy(_M_out_cur, s, sizeof(char_type)*availspace);
		_M_out_cur = _M_out_end;
	}

	// flush and redo
	if(overflow(s[availspace]) != traits_type::eof()) {
		return xsputn(s+availspace, n-availspace);
	} else
		return traits_type::eof();
}

exec_streambuf::int_type exec_streambuf::overflow(int_type c) {
	*_M_out_cur = '\0'; // flush buffer
	if(fwrite(_M_out_beg, sizeof(char_type), 1+_M_out_cur-_M_out_beg, PipeWriter) &gt; 0) {
		fflush(PipeWriter);

		_M_out_cur = _M_out_beg+1; // reset buffer
		*_M_out_beg = c;
		return 1;
	} else {
		return traits_type::eof();
	}
}
</code></pre>
<p>ach, es könnte vielleich helfen, den aufruf aus der main zu haben</p>
<pre><code class="language-cpp">execstream P(argv[1]);
char input[256];
string output;
while(true) {
	cin.getline(&amp;input[0],256);
	P &lt;&lt; input &lt;&lt; &quot;\n\n&quot;;
	P.flush();
	P &gt;&gt; output;
	cout &lt;&lt; output &lt;&lt; endl;
}
</code></pre>
<p>wer's mal testen will:<br />
<a href="http://www.algorithman.de/storage/ExecStream.h" rel="nofollow">http://www.algorithman.de/storage/ExecStream.h</a><br />
<a href="http://www.algorithman.de/storage/test.cpp" rel="nofollow">http://www.algorithman.de/storage/test.cpp</a></p>
<p>(funktioniert afaik nicht unter windows - weil das afaik den fork nicht unterstützt)<br />
danke!</p>
<p>AlgoMan</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1695827</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1695827</guid><dc:creator><![CDATA[AlgorithMan]]></dc:creator><pubDate>Tue, 14 Apr 2009 16:02:13 GMT</pubDate></item><item><title><![CDATA[Reply to iostream ableiten -&amp;gt; werden &#x5C;n gelöscht? on Tue, 14 Apr 2009 15:37:50 GMT]]></title><description><![CDATA[<p>Ansonsten könnte es auch am abholen der Antwort liegen...</p>
<pre><code class="language-cpp">streamsize exec_streambuf::showmanyc() {
	return _M_in_end - _M_in_cur;
}

streamsize exec_streambuf::xsgetn(char* s, streamsize n) {
	// request can be satisfied
	if(_M_in_cur + n &lt;= _M_in_end) {
		memcpy(s, _M_in_cur, sizeof(char_type)*n);
		_M_in_cur += n;
		return n;
	}

	// fetch rest from buffer
	int avail = showmanyc();
	if(avail &gt; 0) {
		memcpy(s, _M_in_cur, sizeof(char_type)*avail);
		_M_in_cur = _M_in_end;
	}

	// refill buffer and redo
	if(underflow() != traits_type::eof())
		return avail+xsgetn(s+avail, n-avail);
	else
		return avail;
}

exec_streambuf::int_type exec_streambuf::underflow() {
	int read = fread(_M_in_beg, sizeof(char_type), EXECSTREAM_BUFFERSIZE, PipeReader); // is this blocking??
	if(read &lt;= 0) { // error or eof
		_M_in_end = _M_in_beg;
		_M_in_cur = _M_in_beg;
		return traits_type::eof();
	}

	// success
	_M_in_end = _M_in_beg + read;
	_M_in_cur = _M_in_beg;
	return *_M_in_beg;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1695831</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1695831</guid><dc:creator><![CDATA[AlgorithMan]]></dc:creator><pubDate>Tue, 14 Apr 2009 15:37:50 GMT</pubDate></item></channel></rss>