2010-12-10 6 views
3

Ich habe einige Parsing-Code, der für ermöglicht Escape-Sequenzen in eine Kette von Text eingegeben werden:Gibt es ein "unput" für std :: ostream, wie es existiert "get" für std :: istream?

// In a file or large, multi-line string ... 
my_parameter="A setting for the parameter\nthat contains \"escape sequence\" characters" 

Wenn ich es analysieren, verarbeiten ich die Schrägstriche und fügen Sie den entsprechenden Zeichen der Zeichenfolge, die ich verwende den Bau eine std::ostringstream Instanz. Zeilenumbrüche, Anführungszeichen, Backslashes und dergleichen funktionieren einwandfrei. Wie auch immer, ich überlegte, ob ich die \b Sequenz erlauben sollte oder nicht, und ging hin, um zu sehen, ob ich das letzte Zeichen von meinem ostringstream "ausgeben" kann, wie Sie von jedem std::istream "getauften" können. Kannst du so etwas tun? Wenn die Funktion nicht existiert, gibt es eine einfache Möglichkeit, die Schreibposition um ein Zeichen zurückzuschieben und einfach das nächste gelesene Zeichen zu überschreiben?

Dies ist nicht missionskritisch oder so, aber ich war neugierig, ob noch jemand darüber schon einmal gestolpert ist.

Antwort

9

Streams sind sehr viel wie die Post. Jede Nachricht, die in einem Stream gesendet wird, ist wie ein Brief, und Nachrichten können in Puffer eingereiht werden, die wie Postfächer sind.

Wenn Sie sowohl für das Eingeben von Nachrichten als auch das Entnehmen von Nachrichten aus einer Mailbox verantwortlich sind, können Sie sicher wissen, dass ein Brief, den Sie gerade dort abgelegt haben, noch da ist. Natürlich würden Sie sich wahrscheinlich nicht die Mühe machen, es in einen Briefkasten zu legen, da Sie beide Enden besitzen.

Wenn Sie stattdessen einen Brief in Ihren Freundinnen-Briefkasten legen, haben Sie nicht wirklich viel Kontrolle darüber, wann sie ihren Briefkasten überprüfen und alle Briefe herausnehmen wird. Es könnte sein, dass sie an der Tür sitzt und den Brief schnappt und ihn liest, sobald er durch den Schlitz geht.

Wahrscheinlicher, Sie liefern den Brief tatsächlich an eine Box, die dem Postamt (dem Betriebssystem) gehört. Obwohl viele solcher Behälter nur Abfallbehälter sind und der Postbote sie einmal pro Tag überprüft, kann es sein, dass der Schacht direkt mit einer Sortiermaschine verbunden ist, und der Brief wird in dem Moment geliefert, in dem Sie ihn fallen lassen.

In einer Streaming-Schnittstelle mit Nebenläufigkeit gibt es keine allgemeine Möglichkeit, den Besitz eines einmal geschriebenen Schreibvorgangs zurückzuerobern. Wenn Sie das benötigen, sollten Sie einen Zwischenpuffer zwischen Ihnen und dem Stream platzieren und ihn nur dann in den Stream auslagern, wenn Sie sicher sind, dass Sie bereit sind.

+0

Kinda dachte, dass das der Fall war.Ich denke, auf lange Sicht werde ich einfach nicht zulassen, dass das '\ b' verwendet wird (ganz ehrlich, es sollte sowieso nicht nötig sein, dies im Zusammenhang mit dieser Anwendung zu tun) und muss sich nicht darum kümmern. Nur eine dieser seltsamen "Ich frage mich, ob ich ..." Fragen. – Will

+0

Sie könnten einen lokalen Puffer einrichten, um die '\ b's zu verarbeiten; Es wird allgemein akzeptiert, dass die Rücktaste eine neue Zeile nicht rückgängig machen kann, sodass Sie nur eine Zeile auf einmal puffern müssen. Übrigens macht die Befehlszeile dies bereits, wenn sie Informationen an das Programm auf der Standardeingabe übergibt. Oder Sie könnten Literal-Backspace-Zeichen senden und das empfangende Ende entscheiden lassen, wie mit ihnen umzugehen ist. –

1

Sie können seekp verwenden, um die Position des Cursors im Stream festzulegen (siehe: http://cplusplus.com/reference/iostream/ostream/seekp/).

+0

das war eine Idee, die ich hatte. Problem kann ins Spiel kommen, wenn die Rücktaste das letzte Zeichen in der Zeichenkette war - selbst wenn ich ein Zeichen zurücksuche, bekomme ich immer noch dieses letzte Zeichen, wenn ich 'str()' auf meinem 'ostringstream' rufe? – Will

0

Wenn Sie einen Charakter zurücknehmen möchten, senden Sie ihn erst, wenn Sie sicher sind, dass Sie ihn nicht zurücknehmen möchten. Sie könnten Ihre eigene „erlauben takebacks“ Logik implementieren somit:

 
int pending_ch = -1; 
void output_char(int ch) 
{ 
    if (pending_ch >= 0) 
    putch(F, ch); 
    pending_ch = ch;  
} 
void unput_char(void) 
{ 
    pending_ch = -1; 
} 
void force_put_char(void) 
{ 
    output_char(-1); 
} 

Ein bisschen klobig, aber das allgemeine Konzept kann zur Verzögerung Ausgang zu einem Strom nützlich sein.

+0

Was passiert, wenn er mehr als eine Rücktaste hintereinander wünscht? – Puppy

+0

Dann muss man mehr Zeichen als das puffern. Analogie mit Ungetc würde jedoch nur ein Zeichen von "Rückführung" erfordern. – supercat

0

Sie könnten einfach ein Backspace-Zeichen selbst eingeben. Ich habe es zumindest in der Windows-Konsole gemacht. Dies sollte sicherstellen, dass das korrekte Verhalten unabhängig vom Zielort eingehalten wird.

+0

an der Konsole, ja, es funktioniert wie erwartet, aber ich arbeite einfach mit Daten im Speicher ... Zeichenfolge möglicherweise oder nicht angezeigt werden, und höchstwahrscheinlich in einer einfachen GUI. – Will

Verwandte Themen