Nur bestimmte Zeilen aus Datei auslesen



  • Hi!

    Habe eine kleine Frage. Möchte zeilenweise eine unbestimmte Anzahl von integer Werten aus einem file auslesen.
    Datei sieht in etwa so aus:

    112312332
    23321
    111111111113212

    Also 3 Zeilen, mit max 100 Werten/Zeile. Das ganze soll in das globale int array sequence [100] rein.
    So wie es im Moment unten dargestellt ist liest er alle Zeilen hintereinander ein, und füllt den Rest danach mit Nullen.
    Kann ich in die while Abfrage auch noch irgendwie reinbasteln dass er jede Zeile nur bis \n einliest?
    Dann noch was. Abängig von einem übergebenen Parameter soll er wahlweise eine der drei Zeilen einlesen.
    Geht das auch mit fscanf? ZB. über eine if Afrage, und dann mit fscanf("\n %d..., bzw. mit fscanf("\n \n %d...?

    Viele Grüße!
    Christian

    PS Ach noch was. Danach möchte ich das array sequence [100] in ein anderes kopieren. Dazu habe ich mir den Befehl memcpy(info.sequence, sequence, sizeof(sequence)); ausgesucht. Wenn das dann so klappt dass er mir nur die gewünschte Anzahl an ints einliest, und nicht zusätzliche Nullen, werden dann mit diesem Befehl auch nur die relevanten Daten in das andere array kopiert?

    void
    read_sequence(char s)
    {
    	int i = 0;
    	FILE *h = fopen("sequences", "r");
    	if (!h)
    	{
    		fprintf(stderr, "Can't open sequence file: %s\n", strerror(errno));
    		exit(1);
    	}
    
    	while(fscanf(h, "%d", &sequence[i]) != EOF)
    		i++;
    	fclose(h);
    	for (i=0; i<100; i++)
    		printf("%d", sequence[i]);
    }
    


  • Also erstmal:

    Um Zeilenweise Daten auszulesen, eigent sich fgets() besonders gut.

    fgets ( buffer, 100, p_teststream );
    

    Und um einen String/Char-Array zu bearbeiten, empfehle ich den Abschnitt

    String Manipulation

    in der MSDN.

    €dit:
    Oder die C++ Referenz

    http://cplusplus.com/reference/clibrary/cstring/



  • Wow 🙂

    Erstmal: danke.
    Und noch allgemein: ich bin immer wieder überrascht wie verdammt schnell man hier Antwort bekommt!!

    Ich werde es gleich ausprobieren...



  • So langsam bin ich am verzweifeln. Hab heute anscheinend keinen guten Tag, oder es ist schwerer als ich es mir denke. Habe zuletzt folgendes probiert mit fgets:

    void
    read_sequence(char s)
    {
    	int i,j;
    	FILE *h = fopen("sequences", "r");
    	if (!h)
    	{
    		fprintf(stderr, "Can't open sequence file: %s\n", strerror(errno));
    		exit(1);
    	}
    
    	for (i=0 ; i<3; i++)
    	{
    		while(fgets(sequence[i], 100, h))
    		{
    			printf("line: %i", sequence[i]);
    		}
    		printf("EOF\n");
    	}
    
    	fclose(h);
    
    }
    

    Mittlerweile ist sequence ein mehrdim. array: int sequence [3] [100];

    Ich erhalte folgende Fehler:

    rshaperctl.c: In function ‘read_sequence’:
    rshaperctl.c:209: warning: passing argument 1 of ‘fgets’ from incompatible pointer type
    rshaperctl.c:211: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘int *’
    

    Output ist nur wirres Zeug.
    Wieso klappt das so nicht?



  • Ich habs mal n bisserl überarbeitet:

    void read_sequence ( char *s )
    {
        char *lines[100];
        FILE *stream;
    
        if ( ( stream = fopen( s, "rt") ) = NULL)
        {
            fprintf(stderr, "Can't open sequence file: %s\n", strerror(errno));
            exit(1);
        }
    
        for ( int i = 0; i <= 3; i++ )
        {
            fgets( lines[i], 100, stream )
            printf("line: %s", lines[i] );
        }
        printf("EOF\n");
    
        fclose( stream );
    }
    

    Nicht getestet !



  • Zu Shapeshifter: dein Array sollte vom Typ 'char' sein!

    Zu Pyro Phoenix: "char *lines[100]" ist bei dir großer Unsinn, da du mittels lines[i] auf ungültigen Speicher zugreifst (da nicht initialisiert)!

    Also hier nochmal richtig:

    char sequence[3][100];
    

    P.S. Und bei der Ausgabe mußt du dann "%s" verwenden.

    Wenn du dann die einzelnen Ziffern aus dem String 'sequence[i]' in ein int-Array haben willst, dann mußt du sie einzeln kopieren und für jedes einzelne Zeichen '0' davon abziehen:

    int x = sequence[i][j] - '0';
    

    Du mußt dir über den Unterschied zwischen (ASCII-) Zeichen und Zahlen klar werden.



  • Hi, Danke für die Tipps.
    Leider läuft es immer noch nicht ganz.
    Das mein (Verständnis-)problem ist wohl generell: Wie teile ich fgets() mit welche Zeile es einlesen soll?
    Wieso liest er hier nicht wenigstens die ersten hundert Werte voll ein?

    Hier die Daten:

    void
    read_sequence()
    {
    	int i,j;
    	FILE *h = fopen("sequences", "r");
    	if (!h)
    	{
    		fprintf(stderr, "Can't open sequence file: %s\n", strerror(errno));
    		exit(1);
    	}
    
    	for (i=0 ; i<3; i++)
    	{
    		fgets(sequence[i], 100, h);
    		printf("Sequence line %d: %s\n", i, sequence[i]);
    		puts("break");
    	}
    	fclose(h);
    }
    

    mit

    char sequence [3][100];
    

    Output:

    Sequence line 0: 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
    break
    Sequence line 1:  2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2
    break
    Sequence line 2: 4
    
    break
    

    Original sequence file (3 Zeilen mit jeweils 100 Werten):

    1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 4
    1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 4
    2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 4
    

Anmelden zum Antworten