sscanf richtig benutzen



  • hi,

    ich würde gerne ein text aus zahlen mit unbestimmter größe mittels sscanf in in ein int array kopieren.

    char text[] = "10 20 30 40 50";
    int arr[10];
    sscanf( text, "%d", .. )..
    // keine ahnung wie ich das richtig hinbekomme, hoffe ihr könnt mir helfen.
    


  • char text[] = "10 20 30 40 50";
    int arr[10];
    sscanf (text, "%d %d %d %d %d", &arr[0], &arr[1], &arr[2], &arr[3], &arr[4]);
    

    Hier kannst du sehen, wie's generell funktioniert.



  • wenn du nicht weisst wie lang die zahlen sind solltest du anders vorgehen und die zahlen mit strtol rausfischen http://www.cplusplus.com/reference/clibrary/cstdlib/strtol/



  • könnte das nich so gehen?
    also dieser text mit zahlen kann unterschiedlich viele zahlen enthalten.

    char text[] = "1 2 3 4 5 6 7 10 20 30 40 123 456";
    int *x;
    sscanf(text, "%*d", &x);
    

    was wäre denn die einfachste möglicheit das zu lösen?



  • sscanf bietet leider keine möglichkeit das irgendwie variabel zu machen



  • Mach doch eine Schleife und einen Pointer auf deinen String, den du pro Durchlauf entsprechend erhöhst (also auf die nächste Zahl zeigen lässt).



  • ok dann werde ich das so machen, wie du es vorgeschlagen hast.
    danke vielmals



  • hm ich schaff es nich eine funktion zu schreiben, die mir ein int array zurückgibt. als parameter will ich den text übergeben text[] = "10 20 30";

    und will dann sie so ungefähr aufrufen:
    int *x = function( text );

    dann habb ich in x[0] 10, x[1] 20, usw.



  • int *func (char *text) {
       int *arr;
       ... // Speicher allozieren usw.
       return arr;
    }
    

    Vergiss aber nicht, am Ende, den Speicher wieder freizugeben.



  • monstermunchkin schrieb:

    int *func (char *text) {
       int *arr;
       ... // Speicher allozieren usw.
       return arr;
    }
    

    Vergiss aber nicht, am Ende, den Speicher wieder freizugeben.

    Da fänd' ich es aber besser, wenn der int-Pointer auch der Funktion übergeben wird, so dass der Speicher vom Aufrufer angefordert und freigegeben wird.



  • _matze schrieb:

    monstermunchkin schrieb:

    int *func (char *text) {
       int *arr;
       ... // Speicher allozieren usw.
       return arr;
    }
    

    Vergiss aber nicht, am Ende, den Speicher wieder freizugeben.

    Da fänd' ich es aber besser, wenn der int-Pointer auch der Funktion übergeben wird, so dass der Speicher vom Aufrufer angefordert und freigegeben wird.

    Wie man's macht, ist doch eine Sache des Geschmacks. Ich sehe bei meinem Ansatz keinen erheblichen Nachteil, aber ich lasse mich gerne eines Besseren belehren 😉



  • monstermunchkin schrieb:

    Wie man's macht, ist doch eine Sache des Geschmacks. Ich sehe bei meinem Ansatz keinen erheblichen Nachteil, aber ich lasse mich gerne eines Besseren belehren 😉

    Na ja, es ist aber grundsätzlich ratsam, Speicher immer an der Stelle freizugeben, an der er auch angefordert wird. Wenn du diese Funktion geschrieben hast und dann verwendest, siehst du ja keinen Hinweis darauf, dass der Aufruf der Funktion unbedingt mit einem free verbunden werden muss. Wenn du die Funktion gerade geschrieben hast, erinnerst du dich noch daran. Wenn du sie Monate später benutzt (oder gar jemand anderes), vielleicht nicht mehr. Wenn nun aber der Aufrufer 'gezwungen' wird, den nötigen Speicher zu allokieren, wird er auch eher daran denken, diesen wieder freizugeben, weil dies dann quasi auf derselben Ebene passiert.

    EDIT: Außerdem bleibt so der Rückgabewert frei, falls man ihn z.B. für einen Errorcode verwenden will.
    EDIT2: Und wenn es darum geht, dass man die Funktion gerne in Ausdrücken verwenden will, hindert einen ja keiner daran, zusätzlich noch einen Zeiger auf das Array zurückzugeben.



  • Nun ja, klingt alles recht plausibel. Vielleicht kann ich mich ja damit anfreunden; Danke Dir 🙂



  • _matze schrieb:

    Na ja, es ist aber grundsätzlich ratsam, Speicher immer an der Stelle freizugeben, an der er auch angefordert wird. ...

    Ha ! Sorry Matze, aber das ist ein extrem schlechter, unflexibler Programmierstil.



  • exj schrieb:

    _matze schrieb:

    Na ja, es ist aber grundsätzlich ratsam, Speicher immer an der Stelle freizugeben, an der er auch angefordert wird. ...

    Ha ! Sorry Matze, aber das ist ein extrem schlechter, unflexibler Programmierstil.

    Nein, das ist ein übersichtlicher Stil, der weniger fehleranfällig ist. Wenn man unbedingt in einer tieferen Funktion Speicher allozieren muss, dann sollte man auch ein entsprechendes Gegenstück basteln, so dass man ein ...New/...Delete Konstrukt hat. Das ist dann für jeden verständlich: zu jedem ...New-Aufruf gehört nach der Verarbeitung auch ein ...Delete-Aufruf. Aber eine Funktion Speicher anfordern lassen und dann darauf hoffen, dass jeder Benutzer der Funktion auch am Schluss ein passendes free notiert... nö, finde ich nicht gut.



  • _matze schrieb:

    Aber eine Funktion Speicher anfordern lassen und dann darauf hoffen, dass jeder Benutzer der Funktion auch am Schluss ein passendes free notiert... nö, finde ich nicht gut.

    Klar. Aber es gibt hin und wieder schon Funktionen, die selbst Speicher holen, den der Aufrufer dann freigeben muss, zB malloc().
    🙂



  • _matze schrieb:

    ... Wenn man unbedingt in einer tieferen Funktion Speicher allozieren muss, dann sollte man auch ein entsprechendes Gegenstück basteln, so dass man ein ...New/...Delete Konstrukt hat. ...

    Ahh entschuldige, dann hab ich deinen alten Post total falsch verstanden. Ich dachte du wärste generell gegen Funktionen die einen Pointer auf intern allozierten Speicher zurückgeben.
    In dieser Art mach ich das auch immer Create/Delete und New/Destroy hab ich immer so als Gegenstücke.



  • exj schrieb:

    _matze schrieb:

    ... Wenn man unbedingt in einer tieferen Funktion Speicher allozieren muss, dann sollte man auch ein entsprechendes Gegenstück basteln, so dass man ein ...New/...Delete Konstrukt hat. ...

    Ahh entschuldige, dann hab ich deinen alten Post total falsch verstanden. Ich dachte du wärste generell gegen Funktionen die einen Pointer auf intern allozierten Speicher zurückgeben.
    In dieser Art mach ich das auch immer Create/Delete und New/Destroy hab ich immer so als Gegenstücke.

    Nein, dagegen bin ich sicher nicht. Unser Code ist quasi voll von solchen Beispielen: Handles, die mit ...New angelegt werden, mit allen Funktionen dieses Moduls benutzt werden müssen (also quasi das Objekt, als Klassenersatz) und am Ende halt wieder aufgeräumt werden müssen.

    mngbd schrieb:

    Klar. Aber es gibt hin und wieder schon Funktionen, die selbst Speicher holen, den der Aufrufer dann freigeben muss, zB malloc().
    🙂

    Aber klar, dann... äh... hasse ich jetzt malloc...? 🤡 😉


Log in to reply