String splitten und zweiten Teil konvertieren



  • Guten Abend
    ich müsste ein String bei einem Leerzeichen splitten und den zweiten Teil in einen int konvertieren.
    Der ganze String sieht z.B. so aus: Hallo 0000

    Habe es schon mit strtok versucht aber damit schmiert das Programm an der Stelle einfach ab.

    MfG
    Tom



  • Schmiert wahrscheinlich ab, weil dein String const ist und strtok den String zerstört.
    Versuchs mal mit sscanf

    int i;
    if( 1==sscanf("Hallo 4711","%*s%d",&i) )
      printf("%d",i);
    


  • Habe es jetzt so gelöst:

    zahl2 = strtok(score, " ");
    zahl2 = strtok(NULL, " ");
    zahl3 = strrchr(zahl2, '\n');
    *zahl3 = '\0';
    umwandel = atoi(zahl2);
    printf("%d\n", umwandel);
    

    das ganze muss ich drei mal machen. Bei den ersten zwei funktioniert es auch nur im dritten gibt er mir die Fehlermeldung: Program received signal SIGSEGV, Segmentation fault aus.
    Hier mal der komplette Codeschnippsel:

    Filehighscore = fopen("highscore.txt","r");
                        zaelen = 0;
                        while ( fgets(score, LINE_LENGTH, Filehighscore) != NULL)
                        {
                            if(zaelen == 0)
                            {
                                zahl2 = strtok(score, " ");
                                zahl2 = strtok(NULL, " ");
                                zahl3 = strrchr(zahl2, '\n');
                                *zahl3 = '\0';
                                umwandel = atoi(zahl2);
                                printf("%d\n", umwandel);
    
                            }
    
                            if(zaelen == 1)
                            {
                                zahl2 = strtok(score, " ");
                                zahl2 = strtok(NULL, " ");
                                zahl3 = strrchr(zahl2, '\n');
                                *zahl3 = '\0';
                                umwandel = atoi(zahl2);
                                printf("%d\n", umwandel);
                            }
    
                            if(zaelen == 2)
                            {
                                zahl2 = 0;
                                zahl3 = 0;
                                zahl2 = strtok(score, " ");
                                zahl2 = strtok(NULL, " ");
                                zahl3 = strrchr(zahl2, '\n');
                                *zahl3 = '\0';
                                umwandel = atoi(zahl2);
                                printf("%d\n", umwandel);
                            }
                            zaelen++;
    
                        }
                        fclose(Filehighscore);
    

    Bei den ersten zwei Funktioniert es aber nicht beim dritten.



  • Guck dir doch mal im Debugger (oder per printf) an, welchen Wert zahl3 = strrchr(zahl2, '\n');
    in deiner dritten if-Anweisung hat.
    Ich nehme an er ist NULL, weil dein highscore.txt kein abschließendes '\n' hat und daher *zahl3 = '\0'; fehlschlägt.

    Rückgabewerte haben schon ihren Sinn, darum sollten sie auch dort wo es sinnvoll ist auch benutzt werden.
    Davon mal abgesehen, brauchst du das '\n' nicht zu überschreiben, weil an der Position atoi von Haus aus aufhört umzuwandeln.

    Wozu sollen denn die drei if Anweisungen eigentlich gut sein, die kannst du rausschmeißen.
    Das sollte im Prinzip das gleiche tun:

    Filehighscore = fopen("highscore.txt","r");
    	if ( Filehighscore != NULL )
    	{
    		 while ( fgets(score, LINE_LENGTH, Filehighscore) != NULL )
    		 {
    			 char* p = strrchr(score, ' ');
    			 int umgewandelt;
    			 if ( p != NULL )
    			 {
    				 umgewandelt = atoi(p);
    				  printf("%d\n", umgewandelt);
    			 }
    
    		  }
    		 fclose(Filehighscore);
    	}
    


  • Ok Danke das wusste ich nicht. Es sollen nur die ersten drei Zeilen ausgegeben werden.
    Das Programm ist ein kleines Quiz was halt noch einen Highscore mitzählt. Dieser soll dann mit eingegeben Namen in die Datei geschrieben werden. Um aber die ereichte Punktzahl vergleichen zu können muss ich den bestehen Wert in einen Int umwandeln.
    Werde das vorgeschlagene heute mittag ausprobieren. Mal sehen ob es klappt.



  • audacity363 schrieb:

    Ok Danke das wusste ich nicht. Es sollen nur die ersten drei Zeilen ausgegeben werden.

    Okay, dann zähle einfach die eingelesenen Zeilen, die ifs brauchst du nicht.

    audacity363 schrieb:

    Das Programm ist ein kleines Quiz was halt noch einen Highscore mitzählt. Dieser soll dann mit eingegeben Namen in die Datei geschrieben werden. Um aber die ereichte Punktzahl vergleichen zu können muss ich den bestehen Wert in einen Int umwandeln.

    Das ginge auch direkt mit fscanf ohne Umwandlung per atoi.
    Prizipiell, siehe Wutzs Beispiel.



  • Habe es jetzt ohne die Ifs gölst:

    if(fragen == 20)
                    {
                        printf("Dein Highscore: %d\n\n", highscore);
                        Filehighscore = fopen("highscore.txt","r");
                        zaelen = 1;
                        while ( fgets(score, LINE_LENGTH, Filehighscore) != NULL)
                        {
                            while(zaelen < 4)
                            {
                                zahl2 = strtok(score, " ");
                                zahl2 = strtok(NULL, " ");
                                umwandel = atoi(zahl2);
                                printf("%d\n", umwandel);
                                if(umwandel < highscore || umwandel == highscore)
                                {
                                    printf("Du hast den %d Platz gemacht\n", zaelen);
                                    zaelen = 4;
                                    break;
                                }
                                zaelen++;
                            }
    
                        }
                        fclose(Filehighscore);
                    }
    

    Nur werden jetzt in der zweiten und dritten Zeile nur null ausgelesen.



  • In deinem ersten Beispiel machst du eine Umwandlung pro Zeile, jetzt sind es drei pro Zeile. Das Programm macht nun ganz was anderes.



  • Ok habe es jetzt mal mit sscanf versucht. Nur kann ich dort nur die erste Zeile der Datei auslesen.
    Ebenfalls versteh ich den Befehl nicht richtig. Was hat es mit dem Argument vor dem "=sscanf" auf sich?



  • audacity363 schrieb:

    Was hat es mit dem Argument vor dem "=sscanf" auf sich?

    Hast du gerade erst mit C angefangen?
    Es wird in einer if-Bedingung der Rückgabewert von sscanf abgefragt.
    http://www.cplusplus.com/reference/cstdio/sscanf/

    Zeig doch mal, wie deine Highscore-Textdatei aussieht.



  • Nein arbeite schon etwas länger mit C aber nicht mit sscanf. Dies ist mir bis jetzt noch nicht untergekommen. Mach zurzeit eine Ausbildung zum Fachinformatiker und in diesem Betrieb wird sehr viel mit C gearbeitet. Aber scho nmal vielen dank.
    Habe es jetzt so gelöst und es funktioniert:

    printf("Dein Highscore: %d\n\n", highscore);
                        Filehighscore = fopen("highscore.txt","r");
                        zaelen = 0;
                        while ( fgets(score, LINE_LENGTH, Filehighscore) != NULL)
                        {
                            if(zaelen == 0)
                            {
                                zahl2 = strtok(score, " ");
                                zahl2 = strtok(NULL, " ");
                                umwandel = atoi(zahl2);
                                printf("%d\n", umwandel);
                                if(umwandel < highscore || umwandel == highscore)
                                {
                                    printf("Du hast den ersten Platz gemacht.\n");
                                    platz = 1;
                                }
    
                            }
    
                            if(zaelen == 1)
                            {
                                zahl2 = strtok(score, " ");
                                zahl2 = strtok(NULL, " ");
                                umwandel = atoi(zahl2);
                                printf("%d\n", umwandel);
                                if(umwandel < highscore)
                                {
                                    printf("Du hast den zweiten Platz gemacht.\n");
                                }
                                else
                                {
                                    printf("Du hast den dritten Platz gemacht\n");
                                }
                            }
    
                            if(zaelen == 2)
                            {
                                zahl2 = strtok(score, " ");
                                zahl2 = strtok(NULL, " ");
                                umwandel = atoi(zahl2);
                                printf("%d\n", umwandel);
                                if(umwandel < highscore)
                                {
                                    printf("Du hast den dritten Platz gemacht.\n");
                                }
                                else
                                {
                                    printf("Du hast gar keinen Platz gemacht\n");
                                }
                            }
                          zaelen++;
    

    Es ist noch nicht ganz ausgereift bzw. es müssen ein paar Funktionen noch verändert werden.

    Die Highscore.txt sieht so aus:
    Test1 30
    Test2 20
    Test3 10

    ohne irgendwelche anderen Sachen.



  • Guck dir doch auch mal die Funktion fscanf bzw. fscanf_s an.

    char test[256];
    unsigned score;
    
    while ( 2 == fscanf ( Filehighscore, "%255s %d", test, &score ))
    {
    	printf ( "%s %d\n", test, score );
    }
    


  • Ok habe es jetzt mal mit fscanf versucht nur gibt er dort einen total anderen Wert zurück und zwar 36. Laut Debugger steht dann auch in test nur Platzhalter drinnen aber nichts von Test1 oder 30.



  • dann hast du es wohl falsch versucht.
    zeig doch mal deinen versuch, dann wissen wir mehr, so kann man nur rätseln was du falsch machst.



  • Ich habe es einfach so übertragen.

    Filehighscore = fopen("highscore.txt","r");
                        zaelen = 0;
                        while(2 == fscanf(Filehighscore, "%s255s %d", test, &score))
                        {
                            printf("%s %d\n", test, score);
                        }
    

  • Mod

    audacity363 schrieb:

    "%s255s %d"
    

    Das solltest du noch einmal überdenken.



  • gut habe es jetzt so gemacht:

    printf("Dein Highscore: %d\n\n", highscore);
                        Filehighscore = fopen("highscore.txt","r+");
                        zaelen = 1;
                        while(2 == fscanf(Filehighscore, "%s %d", test, &score))
                        {
                             if(score < highscore || score == highscore)
                                {
                                    printf("Du hast den %d gemacht.\n", zaelen);
                                    printf("Gebe bitte deinen Namen ein: ");
                                    scanf("%s", &name);
                                    printf("%s\n\n", name);
                                 //fprintf(Filehighscore, "%s %d", name, highscore);
                                    break;
                                }
                                else
                                {
                                    zaelen++;
                                }
    
                        }
    

    Habe jetzt noch ein Problem mit dem beschreiben von der Datei. Soll ich dafür ein neuen Thread erstellen oder können wir das auch hier machen?
    Wenn es aucch hier geht folgendes:
    Den fprintf Befehl den ich oben als Kommentar eingefügt habe wird irgendwie nicht beachtet. Also es wird nichts in die Datei geschrieben. Der Combiler gibt aber auch keine Fehler oder Warnungen aus. Der Debuger nimmt ihn so hin gibt aber keine Informationen aus.



  • When a file is opened with update mode ('+' as the second or third character in the
    above list of mode argument values), both input and output may be performed on the
    associated stream. However, output shall not be directly followed by input without an
    intervening call to the fflush function or to a file positioning function (fseek,
    fsetpos, or rewind), and input shall not be directly followed by output without an
    intervening call to a file positioning function, unless the input operation encounters endof-
    file. Opening (or creating) a text file with update mode may instead open (or create) a
    binary stream in some implementations.

    soviel dazu, warum du nichts siehst.
    selbst wenn du etwas siehst wirst du in den meisten fällen
    nicht gerade freudig gestimmt sein, was du zu sehen bekommst.

    - nach dem einlesen zeigt der dateizeiger hinter den gerade eingelesenen
    datensatz. dort möchtest du den höheren wert vermutlich nicht haben.
    - selbst wenn du die richtige stelle per fseek etc ansteuerst, wird der neu einzufügende datensatz in den meisten fällen nicht die größe des zu überschreibenden haben. das sieht dann wirklich nicht schön aus

    abhilfe in groben zügen:

    datei komplett in den speicher einlesen, datei schließen.
    datei im speicher zum schreiben vorbereiten(neuer highscore etc)
    datei neu- bzw. überschreiben.



  • ok habe da ganze wieder mit ifs gelöst :)Sehe sonst keine Möglichkeit die Einzelnen Zeilen zu zählen und aufzureiben.

    while(2 == fscanf(Filehighscore, "%s %d", user, &score))
                        {
                            if(zaelen == 0)
                            {
                                strcpy(uZeile1, user);
                                hZeile1 = score;
                                printf("user Zeile1: %d\n", hZeile1);
                            }
    
                            if(zaelen == 1)
                            {
                                strcpy(uZeile2, user);
                                hZeile2 = score;
                                printf("user Zeile2: %d\n", hZeile2);
                            }
    
                            if(zaelen == 2)
                            {
                                strcpy(uZeile3, user);
                                hZeile3 = score;
                                printf("user Zeile2: %d\n", hZeile3);
                            }
                            zaelen++;
    


  • Wenn du die Variablen uZeile und hZeile als Array anlegst, kannst du das viel eleganter lösen.



  • früher oder später kommst du auch an strukturen nicht vorbei.

    #define NAMELEN_MAX 63
    
    	struct scorelist_dataset
    	{
    		char name[NAMELEN_MAX+1];
    		unsigned score;
    	};
    
    	struct scorelist_dataset dataset[3] = {0};
    	int i = 0;
    
    	fscanf ( fp, "%s %u", dataset[i].name, &dataset[i].score )
    	printf( "%s %u\n", dataset[i].name, dataset[i].score );
    

Anmelden zum Antworten