Umwandlung char (String) nach int



  • Hallo.
    Erst einmal zur Erklärung:
    Habe hier ein GCODE File. Dieses treibt eine Stickmaschine an. Datei kommt aus Inkscape + Plugin Inkstich.
    Darin liegen die X, Y und Z - Werte wie in einer TXT Datei. Also als String.
    Ein Beispiel einiger Zeilen:
    G0 X123,456 Y654,321
    G0 Z0,0
    G0 X12,3 Y43,21
    G0 .....usw.
    Jetzt habe ich mein Programm mit Borland Builder soweit fertig gemacht, das ich die GCODE Datei zeilenweise als String einlesen kann, zur Stickmaschine über USB sende und auf das OK der Stickmaschine warte, bis die nächste Zeile gesendet wird usw.. Das funktioniert auch alles sehr gut und es Stickt auch alles bestens.
    Jetzt aber zu meiner Frage:
    Ich möchte mit der PaintBox aus Borland Builder und dem TCanvas das Stickobjekt in meiner Software anzeigen lassen. TCanvas kann ja sehr gut mit MoveTo(X,Y) und LineTo(X,Y) durch Angabe von X-Y-Koordinaten zeichnen. Das Problem ist aber, das die X-Y-Koordinaten als int-Wert und nicht als String vorliegen müssen.
    Aber ich habe keine Idee, wie ich eine Wandlung der Daten aus dem GCODE File nach int hinbekommen kann.

    1. Idee: Ist es vielleicht möglich die GCODE Datei gleich als int einzulesen und die Zahlen dabei auszusondern?
    2. Idee: Ist es vielleicht möglich, in dem char String nach dem X bzw. Y zu suchen und alles was als Zahl danach erscheint minus 48 dezimal zu nehmen und hinterher mit entsprechender Wertigkeit wieder zusammen zu stückeln?
    3. Idee: ODER! gibt es in C++ etwas was ich noch nicht kenne und was solche Aufgaben sehr elegant lösen kann?

    Ich bin für alle Ideen dankbar.
    Eric



  • Es sieht so aus, als häätest du da Reale Zahlen und keine Integer
    Und ist da wirklich ein , als Dezimaltrennzeichen?

    Es gibt Funktionen im Standard, die Zahlenliterale umwandeln.
    Welche du benutzen kannst, hängt auch davon ab, ob du Real-Zahlen hast, welches Dezimaltrennzeichen da sind und welche Art von String du benutzt.



  • Hallo Dirk
    Ah... Ja das ist kein Komma, da ist eigentliche ein Punkt.

    Welche Art von String? Hm.... char denke ich mal... weiss es aber nicht genau.
    Real-Zahlen? Also ich öffne mit "OpenDialog" und dann mit
    stream = fopen(OpenDailog1->FileName.c_str(), "r");
    Dann lese ich eine Zeile mit:
    fgets(OneLine, sizeof(OneLine), stream); ein.
    Später erkenne ich noch die Anzahl an Zeichen mit:
    int anzahl = strlen(OneLine);

    Ich habe keine Ahnung, in welchem Format dann die Zahlen vorliegen. Ob diese reale Zahlen sind oder nicht..... Bin leider was C++ angeht Neuling. Beim Microkontroller mache ich immer alles in Assembler. Aber auf dem PC geht das leider nicht..... Da kommt man um C++ halt nicht Drumherum....

    Dirk, konnte ich Dir mit diesen weiteren Angaben helfen, damit du mir weiterhelfen kannst?



  • @Eric sagte in Umwandlung char (String) nach int:

    Bin leider was C++ angeht Neuling.

    Das sieht mehr nach C aus (ok, FileName ist ein String-Objekt).

    Ah... Ja das ist kein Komma, da ist eigentliche ein Punkt.

    Da kannst du mit sscanf arbeiten.

    double x, y;
    
    int gelesen = sscanf(OneLine, "G0 X%ld Y%ld", &x, &y);
    if (gelesen == 3) 
    { // jetzt stehen in x und y gültige Werte
      // und du kannst damit arbeiten
    } else {
    // keine gültigen X und y Werte, weil zb. ein Z drin steht
    }
    


  • Hallo Dirk und besten Dank für Deine Hilfe in dieser Sache.
    Ich habe jetzt mal Deinen Code ausprobiert.
    Also Borland Builder meckert darüber überhaupt nicht. Also versteht er auch "sscanf".
    Ich habe mir jetzt einfach nur einen Button eingebaut, der wenn er geklickt wird, eine Zeile einliest mir die eingelesenen Werte in einer Memoanzeige anzeigt und dann gleich darauf Deinen Beispielcode ausführt. Das Ergebnis was in X und Y vorliegt, lasse ich mir über ein EDIT Fenster anzeigen.
    Wenn ich die if (gelesen == 3) Abfrage drin lasse, passiert nichts und else wird abgearbeitet.
    Wenn ich die if-Abfrage weglasse und damit das Programm zwinge mir die Daten in x und y anzuzeigen, dann sind da Werte drin, die nicht passen können.
    Eingang = G0 X150.0 Y300.0 daraus wird dann für X = 9,01415228614799E2 und für Y = 2,17292368994844E-3. Also vom Prinzip ist die Verwendung von sscanf schon die richtige Richtung, nur warum jetzt solch komische Werte in x und y zu finden sind????

    Noch eine andere Frage: Was bedeutet die 3 in der if-Anweisung? if (gelesen == 3) Durch was oder wen wird "gelesen" auf 3 gesetzt?
    Gruß Eric



  • @DirkB Bist Du Dir mit 3 sicher? es sollten 2 sein. Warum keine streams? Und %ld ist auch nicht für doubles, ne ne. Setzen, sechs.

    @Eric sagte in Umwandlung char (String) nach int:

    Noch eine andere Frage: Was bedeutet die 3 in der if-Anweisung? if (gelesen == 3) Durch was oder wen wird "gelesen" auf 3 gesetzt?

    Informier' dich darüber, was sscanf() zurückgibt.



  • Hallo Dirk.

    Habe jetzt noch eine Neuigkeit. Teilweise funktioniert es jetzt! 🙂

    Habe die Deklaration "double" mal auf int gesetzt. Hier passiert jetzt folgendes.
    Aus Datei gelesen: G0 X150.0 Y300.0 daraus wird jetzt X=150, aber der Y-Wert stimmt nicht. Gehe mal davon aus, das ja dann das ganze Konstrukt mit dem Punkt nicht mehr passt...
    Aber ich habe jetzt zumindest mal einen sehr guten Ansatz, wo ich weiter machen kann. Eventuell mache ich auch ein Konstrukt mit sscanf für X und Y separat. So bekähme ich wenigstens die Vorkommastellen ausgelesen. Ich muss sowieso die X und Y Werte mit 10 Multiplizieren. Da brauche ich nicht unbedingt die Nachkommastelle.
    Allerdings wenn du noch eine geniale Idee hättest, das man die komplette Flieskommazahl raus bekäme, dann wäre das natürlich besser...
    Aber vorerst besten Dank für Deine Hilfe. Das hat mir sehr geholfen und ich weiß ja jetzt auch in welche Richtung ich mich informieren muss. Von den "scan" Funktionen/Befehlen oder wie man das auch nennt... gibt es ja noch ein paar mehr. Werde mich mal da reinlesen.
    Danke und Gruß Eric



  • @Eric Gib eine komplette beispieldatei und sag ob C oder C++.



  • @Swordfish
    Was meinst du mit Beispieldatei?

    Eine GCODE Datei, oder den Programmcode?

    Also die GCODE Datei aus der die Werte "G0 X123.34 Y123.34" (Beispielwerte!) ausgelesen werden. ist eine ganz stink normale TXT Datei. Die beginnt mit G0 X.... Y..... \r\n usw. bis zum Ende. Am Ende steht dann M30 nur noch drin, was besagt, das die Datei das Ende erreicht hat.
    Man kann sich eine solche Datei auch mit z.B. Notepad (Windows) selber schreiben.
    Also als Beispiel mit 3 Zeilen:
    G0 X0.1 Y0.2 \r\n
    G0 X1.1 Y1.2 \r\n
    G0 X2.3 Y3.4 \r\n
    3 Zeilen reichen ja vollkommen aus um einen Test durchzuführen.

    Was den Code angeht:
    Nachdem mit dem OpenDialog "Datei->öffnen" wie man ihn aus Windows kennt, die TXT Datei ausgewählt ist, wird diese mit "fopen" geöffnet.

    stream = fopen(OpenDailog1->FileName.c_str(), "r");
    fgets(OneLine, sizeof(OneLine), stream);
    Memo1->Lines->Append(OneLIne);
    double x, y; bzw. NEU int x, y;
    int gelesen = sscanf(OneLine, "G0 X%ld Y%ld", &x, &y);
    Edit1->Text = x;
    Edit2->Text = y;

    Das ist alles was ich an Programmcode habe, um sscanf auszutesten.
    Allerdings das "double" habe ich jetzt halt in "int" verändert.
    Gruß Eric



  • @Eric sagte in Umwandlung char (String) nach int:

    Was meinst du mit Beispieldatei?

    Du geben komplette datei Du einlesen wollen. Du sagen ob C oder C++.

    Wenn Du schreiben Code in Forum hier du bitte schreiben ``` in eine Zeile davor und danach. Danke.

    @Eric sagte in Umwandlung char (String) nach int:

    3 Zeilen reichen ja vollkommen aus um einen Test durchzuführen.

    Nein. Vorher hattest Du auch noch was mit Z. Eine Formatspezifikation wäre natürlich noch besser als ein Beißspiel.



  • @Swordfish
    OK kann auch eine originale GCODE Datei zur Verfügung stellen.
    Aber dumme Frage, wie macht man das hier im Forum? Habe keine Möglichkeit wie "Datei anhängen" oder "Datei hochladen" gefunden.

    Ja vorher hatte ich auch noch Z mit drin. Aber Z hat immer den Wert 0, da Z nur zur Steuerung der Nadel dient. Auch liegt Z immer in einer neuen Zeile. X und Y liegen aber immer zusammen in einer Zeile und nur die Werte von X und Y sind relevant. X und Y kann man sich wie die Steuerdaten eines Plotters vorstellen.



  • @DirkB
    Hallo Dirk.
    Besten Dank für Deine aktive Hilfe. Bin jetzt nach ein bisschen herumspielen mit "sscanf" auf diese Lösung gekommen:
    '''
    int x, x2, y, y2;
    int gelesen = sscanf(OneLine, "G0 X%ld.%ld Y%ld.%ld", &x, &x2, &y, &y2);
    if (gelesen == 4)
    {
    //Jetzt die int Variablen verarbeiten. z.B. (x*1000)+x2 und das selbe für Y.
    //Dadurch bekomme ich eine Ganzzahl, die auch vollkommen ausreicht!
    }
    '''
    Dadurch, das ich nun erst einmal reale Werte für die "Canvas->LineTo(x,y)" aus dem GCODE erhalten konnte, habe ich erst einmal sehen können, das ich eigentlich auch auf die Kommastellen zur Anzeige im PC verzichten kann. Es reicht auch aus, wenn ich den Ganzwert, also das was vor dem Punkt steht mit 4 multipliziere. Das zu stickende Objekt, welches sich im GCODE-File befindet ist jedenfalls am Bildschirm durch die "Canvas-mal-Funktion" deutlich zu erkennen.

    Deine Hilfe hat mich auf neue Ideen gebracht und ich habe wieder viel über die Programmierung lernen können. Ganz besonders, was es doch halt alles für super Funktionen unter C oder C++ gibt von denen ich noch nichts weiß!
    Danke und Gruß Eric.



  • @Eric sagte in Umwandlung char (String) nach int:

    GCODE

    @Eric Da du zu doof bist simpelste Angaben zu liefern und es nichteinmal wert gefunden hast die Frage nach der Sprache zu beantworten: https://github.com/dillonhuff/gpr

    @Eric sagte in Umwandlung char (String) nach int:

    '''

    ``` nicht ''' . hättest bloß kopieren brauchen oder deinen Code markieren und auf das </> über dem Editorfenster klicken.



  • @Eric Du solltest auch die Hinweise der Anderen lesen.

    @Swordfish sagte in Umwandlung char (String) nach int:

    @DirkB Bist Du Dir mit 3 sicher? es sollten 2 sein. Warum keine streams? Und %ld ist auch nicht für doubles, ne ne. Setzen, sechs.

    Da war ich wohl etwas abgelenkt, schäm.
    %lf wäre es gewesen und die 2.



  • @DirkB Ok. Zwei Minus.


Anmelden zum Antworten