Guten Morgen,
ich würde gerne in C/C++ eine String an eine Funktion übergeben, die
einen "const char *msg_str" erwartet. Also einen Zeiger auf einen
char-Array bzw. String.
Einen String "Signal" habe ich bereits. Hinzu kommt eine Signalnummer,
die als int-Wert vorliegt. Jetzt möchte ich beide miteinander verknüpfen
und das Ganze als String zusammenführen, um sowohl den String "Signal"
also auch die Signalnummer beide in einem gemeinsamen String zu
übergeben.
Also einfache Lösung bin ich wie folgt vorgegangen:
1
chatstr[20];
2
sprintf(str,"%s %d",charSignal,signr);
Somit habe ich char und Signalnr. in einem String. Es ist eine einfache
Lösung, aber wie würde man überlicherweise richtig vorgehen?
Meine zweite Frage bezieht sich ebenfalls auf Strings. Bisher habe ich
Message Queues genutzt, um Nachrichten zwischen Client und Server zu
senden. Mit fgets(buffer, MAXSIZE, 0); habe ich den Vorteil gehabt, dass
ich bei Zeichenüberlauf MAXSIZE-1 an den Server gesendet habe und die
restlichen Zeichen dann im zweiten Durchgang gesendet wurden.
Jetzt zu meiner Frage: fgets() funktioniert nur mit der Usereingabe
(z.B. stdin). Was ist, wenn ich nicht mit der Usereingabe arbeite,
sondern einfach ein Überlanges String senden möchte, und bei einem
Überlauf die restlichen Zeichen ebenfalls in einem zweiten Durchlauf
senden möchte. Gibt es dafür auch eine Lösung?
LXD schrieb:> Also einfache Lösung bin ich wie folgt vorgegangen:> chat str[20];> sprintf(str, "%s %d", charSignal, signr);>> Somit habe ich char und Signalnr. in einem String. Es ist eine einfache> Lösung, aber wie würde man überlicherweise richtig vorgehen?
Einfache Lösungen sind meistens die richtigen. Wenn der String "Signal"
konstant ist, kannst Du ihn natürlich auch direkt im Formatstring
angeben:
1
sprintf(str,"Signal %d",signr);
> Jetzt zu meiner Frage: fgets() funktioniert nur mit der Usereingabe> (z.B. stdin). Was ist, wenn ich nicht mit der Usereingabe arbeite,> sondern einfach ein Überlanges String senden möchte, und bei einem> Überlauf die restlichen Zeichen ebenfalls in einem zweiten Durchlauf> senden möchte. Gibt es dafür auch eine Lösung?
Schau Dir mal snprintf und dessen Rückgabewert an.
Es ist eine einfache Lösung, aber im Netz kursieren ziemlich
komplizierte Möglichkeiten über spezielle C++-Funktionen und mit eine
für Anfänger nicht ganz nachvollziehbaren Syntax.
Einziges Problem: Ich kann nicht zur laufzeit bestimmen, wie groß der
String chat str[20]; sein soll. Daher auch die Alternative mit dem
Abfangen vom Überlauf.
Ist aber keine Standartfjunktion von Linux. sprintf funktioniert in
Bezug auf die Kombination von int und char. Man könnte auch die Funktion
string_to nehmen.
Mein Problem ist jetzt dies, dass ich bei einem Array-Überlauf nur meine
X-Zeichen bekomme. Mit fgets hatte ich den Vorteil, dass die restlichen
zeichen bei einem Überlauf in den Puffer kopiert wurden und beim
erneuten Aufrufen auch ausgegeben wurden. Gibt es eine Funktion, mit der
ich dasselbe erreiche, jedoch nicht mit stdin, sondern ganz normal mit
einem const-Array?
Nein. Ein snprintf, das den Rest, der nicht in den übergebenen Puffer
passt, irgendwo anders "aufhebt", gibt es nicht.
Wenn Du auf einem Betriebssystem unterwegs bist, kannst Du natürlich
fprintf in eine Datei (memory file, pipe, whatever) ausgeben lassen und
das Resultat wiederum mit fgets in beliebiger Stückelung abholen.
Mir scheint dann aber das gesamte Konzept etwas fragwürdig zu sein;
warum sollte es beim Aufruf von (sn)printf einen Pufferüberlauf geben?
Weißt Du nicht, welche Argumente Du übergibst?
Naja, eine Möglichkeit ist es, snprintf mit 0 als Puffergröße
aufzurufen. Der Rückgabewert ist dann die benötigte Puffergröße (ohne
terminierende Null).
Dein Programm kann dann den Puffer dynamisch via malloc & Co. anfordern.
LXD schrieb:> ich würde gerne in C/C++ eine String an eine Funktion übergeben, die> einen "const char *msg_str" erwartet.
Zunächst musst du dich entscheiden, ob es C oder C++ sein soll. Das sind
nämlich zwei verschiedene Sprachen.
LXD schrieb:> Es ist eine einfache Lösung, aber im Netz kursieren ziemlich> komplizierte Möglichkeiten über spezielle C++-Funktionen und mit eine> für Anfänger nicht ganz nachvollziehbaren Syntax.
Hm, ok.
> Einziges Problem: Ich kann nicht zur laufzeit bestimmen, wie groß der> String chat str[20]; sein soll. Daher auch die Alternative mit dem> Abfangen vom Überlauf.
Hier kommt dann die Frage ins Spiel, ob es C oder C++ sein soll. In C++
könnte man auch einen std::stringstream nehmen und hätte dann keinen
Überlauf, da sich die Größe automatisch anpasst.
Sieht dann etwa so aus:
1
std::stringstreamstream;
2
stream<<charSignal<<' '<<signr;
3
std::strings=stream.str();
4
msg_str=s.c_str();
5
// Achtung: msg_str bleibt nur so lange gültig, wie der String existiert
LXD schrieb:> Ist aber keine Standartfjunktion von Linux.
Natürlich ist snprintf eine StandarD-Funktion. Es dürfte zumindest aus
diesem Jahrhundert keine Linux-Distro geben, die diese Funktion nicht
hat.
> sprintf funktioniert in Bezug auf die Kombination von int und char. Man> könnte auch die Funktion string_to nehmen.
Eine Funktion mit diesem Namen wäre mir unter Linux nicht bekannt, auch
eine man-Page habe ich dafür im Gegensatz zu snprintf nicht.
> Mit fgets hatte ich den Vorteil, dass die restlichen zeichen bei einem> Überlauf in den Puffer kopiert wurden und beim erneuten Aufrufen auch> ausgegeben wurden. Gibt es eine Funktion, mit der ich dasselbe erreiche,> jedoch nicht mit stdin, sondern ganz normal mit einem const-Array?
Man könnte fgets() dafür vergewaltigen, indem man einen Memory-Puffer
mit fmemopen() erstellt. Den kann man mit fgets() verwenden.
Rolf M. schrieb:>> sprintf funktioniert in Bezug auf die Kombination von int und char. Man>> könnte auch die Funktion string_to nehmen.>> Eine Funktion mit diesem Namen wäre mir unter Linux nicht bekannt, auch> eine man-Page habe ich dafür im Gegensatz zu snprintf nicht.
Er meint wohl eher std::to_string
http://www.cplusplus.com/reference/string/to_string/
Kaj schrieb:> Er meint wohl eher std::to_string> http://www.cplusplus.com/reference/string/to_string/
Ich sollte doch mal etwas ausführlicher in C++11ff schauen. Da gibt's
immer wieder Dinge, die mich überraschen. Wobei: Wo sind denn bei diesen
Funktionen die Formatierungsoptionen? Ohne die ist das doch nur recht
eingeschränkt brauchbar.
Rufus Τ. F. schrieb:> Willkürlicher Treffer:
Die Stream-Operatoren kenne ich natürlich. Die sind aber auch eher
unhandlich, wenn man nur einen int in einen String konvertieren will -
eigentlich sind sie immer unhandlich.
Rufus Τ. F. schrieb:> Ich weiß, warum ich beim guten alten printf bleibe.
Ich finde es bei Qt ganz gut gelöst.