Forum: PC-Programmierung Typenumwandlung int/char


von LXD (Gast)


Lesenswert?

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
chat str[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?

von Hans (Gast)


Lesenswert?

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.

von LXD (Gast)


Lesenswert?

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.

von Jim M. (turboj)


Lesenswert?

LXD schrieb:
> Einziges Problem: Ich kann nicht zur laufzeit bestimmen, wie groß der
> String chat str[20]; sein soll

Dafür gäbe es snprintf().

von LXD (Gast)


Lesenswert?

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?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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?

von LXD (Gast)


Lesenswert?

Doch, aber es hat mich einfach interessiert, ob es eine Methode gibt.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von Rolf M. (rmagnus)


Lesenswert?

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::stringstream stream;
2
stream << charSignal << ' ' << signr;
3
std::string s = 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.

von Kaj (Gast)


Lesenswert?

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/
1
#include <iostream>
2
#include <string>
3
4
int main()
5
{
6
    int signr = 42;
7
    char const *charSignal = "Signal: ";
8
9
    std::string str = charSignal + std::to_string(signr);
10
11
    std::cout << str << std::endl;
12
13
    return 0;
14
}
1
Signal: 42

von Rolf M. (rmagnus)


Lesenswert?

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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Rolf M. schrieb:
> Wo sind denn bei diesen Funktionen die Formatierungsoptionen?

Willkürlicher Treffer:

https://arachnoid.com/cpptutor/student3.html


Ich weiß, warum ich beim guten alten printf bleibe.

von Rolf M. (rmagnus)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.