Matrixwerte aus einer Datei lesen und in ein Feld speichern



  • Hallo,

    ich muss noch eine Frage stellen, da mir der obige Code noch nicht ganz klar ist.
    Wie muss ich die Routine erweitern, um Kommentarzeilen noch abzufangen.

    Gruß,

    W2K2005



  • W2K2005 schrieb:

    Hallo,

    ich muss noch eine Frage stellen, da mir der obige Code noch nicht ganz klar ist.
    Wie muss ich die Routine erweitern, um Kommentarzeilen noch abzufangen.

    Gruß,

    W2K2005

    Wie sollen die Kommentarzeilen aussehen?



  • W2K2005 schrieb:

    Ich kannte fscanf noch nicht wirklich gut - Du ließt in der Zeile mit der if-Anweisung die Werte in das Datenfeld ein. Stimmts?
    Ließt fscanf die Werte einzeln ein oder wie muss ich mir das vorstellen.

    Ja, die Werte werden einzeln gelesen.

    fscanf "%d" verfährt so:
    - überlies alle Leerzeichen (inkl. Zeilenumbrüche)
    - ist das nächste Zeichen eine Ziffer, lies alle Ziffern und bilde einen Zahlenwert (int).
    - schreibe das Ergebnis an die Adresse, die als nächster Parameter übergeben wurde (&table[y][x]).

    die if-Anweisung prüft das Ergebnis von fscanf() und vergleicht es mit 1.
    Wurde der Wert erfolgreich gelesen, liefert fscanf() den Wert 1 und die Bedingung wird nicht erfüllt.
    (siehe Kommentare im Beispiel)

    W2K2005 schrieb:

    So, nun aber noch einmal eine genauere Beschreibung des Problems:
    Einerseits möchte ich mit der Funktion eine Matrix [200x2] einlesen, zum anderen wollte ich aber auch PArameter, die in einer Zeile stehen so schnell einlesen (aus einer CONFIG-Datei...)

    Wie würdest Du da verfahren??

    Bsp.:

    GRIDFILE
    ---------------
    Pts i j
    250 23 11

    Vielen Dank.

    Gruß,

    W2K2005

    Je nachdem, was Du damit machen willst, kann das durchaus eine größere Geschichte geben.

    Wenn z.B. die Anzahl der Spalten variabel sein soll.

    In dem Fall würde ich Dir eher raten, einen Parser für Deine Config-Dateien zu schreiben.

    Du könntest natürlich auch fscanf() nehmen, und z.B. prüfen, ob eine Zahl oder ein Text vorliegt:

    if ( fscanf( fp, "%d", &val ) == 1 ) ... /* Zahl */
    if ( fscanf( fp, "%s", buf ) == 1 ) ... /* Wort */
    

    Du solltest Dich natürlich mit der Verwendung von if ... else ... Konstruktionen auskennen,
    und Dir mal die Dokumentation zu fscanf() genau ansehen.



  • Hi,

    vielen Dank für Deinen letzten Eintrag - ich glaube langsam auf den richtigen Weg zu kommen.

    Also, ich lese nun meine Kommentarzeilen mit fgets weg (insgesamt 2).

    char tBuffer[256];
    FILE *stdptr;
    
    fgets(tBuffer, 256, stdptr);
    fgets(tBuffer, 256, stdptr);
    

    In der nächsten Zeile der Datei stehen nun meine ersten 3 Zahlenwerte; getrennt durch Leerzeichen. Aber ich bekomme mit fscanf keine Werte in meine Variablen i_max, j_max und dim_ij... Woran liegt das? Habe die online-Hilfe aufgesucht und verstehe die Parameterlist nach meiner Meinung richtig.

    if (fscanf(stdptr, "%d", &i_max, &j_max, &dim_ij) == 1) {
      // Einlesen der Werte war erfolgreich
    }
    

    Noch eine kurz Frage zum Schluss. Steht mein Dateipointer nun in der nächsten Zeile meiner Datei? Ich frage mich was ich machen müsste, wenn beispielsweise 4 Werte in einer Zeile stehen und ich mit fscanf aber nur 3 einlesen will, um dann in die nächste Zeile zu springen und den Vorgang zu wiederholen...(Schleife)!

    Vielen Dank und noch einen schönen Abend.

    gruß,

    W2K2005



  • W2K2005 schrieb:

    In der nächsten Zeile der Datei stehen nun meine ersten 3 Zahlenwerte; getrennt durch Leerzeichen. Aber ich bekomme mit fscanf keine Werte in meine Variablen i_max, j_max und dim_ij... Woran liegt das? Habe die online-Hilfe aufgesucht und verstehe die Parameterlist nach meiner Meinung richtig.

    if (fscanf(stdptr, "%d", &i_max, &j_max, &dim_ij) == 1) {
      // Einlesen der Werte war erfolgreich
    }
    

    Noch eine kurz Frage zum Schluss. Steht mein Dateipointer nun in der nächsten Zeile meiner Datei? Ich frage mich was ich machen müsste, wenn beispielsweise 4 Werte in einer Zeile stehen und ich mit fscanf aber nur 3 einlesen will, um dann in die nächste Zeile zu springen und den Vorgang zu wiederholen...(Schleife)!

    Du mußt so viele "%d" schreiben, wie Du Variablen einlesen willst, also z.B.

    if ( fscanf(stdptr, "%d %d %d" /* <-- hier */ , &i_max, &j_max, &dim_ij) == 3  /* <-- und hier */ ) {
      // Einlesen der Werte war erfolgreich
    }
    

    Ein Leerzeichen im Format-String: " ", sorgt auch dafür, daß Leerzeichen überlesen werden.

    Danach steht der Dateizeiger hinter der letzten eingelesenen Ziffer. Da ja Zeilenumbrüche automatisch überlesen werden, kannst Du in der nächsten Zeile gerade so weitermachen.

    Bevor Du jedoch wieder fgets() aufrufst, mußt Du sicherstellen, daß Du bei einer neuen Zeile angekommen bist. Du kannst auch einfach so viele fgets() Aufrufe einfügen wie notwendig, da das den selben Effekt hat (Du liest dann das ein, was hinter den Zahlen vor der nächsten Zeile steht, also im Idealfall nur ein Zeilenumbruch).

    Oder Du hängst noch ein Leerzeichen an den Format-String an: "%d %d %d ", damit gehst Du auf Nummer sicher, daß bis zum nächsten Zeilenanfang gelesen wurde.



  • Hi,

    vielen Dank zunächst für den letzten Hinweis. Ich verstehe aber einen Deiner letzten Kommentare nicht ganz.
    Angenommen, folgendes steht in meiner CONFIG-Datei:

    1. GRIDFILE - CUBE
    2. ----------------------------------
    3. PTS    I   J   K
    4. 231    11  20  1  5
    5. 0.00  0.00  0.00
    6. 0.05  0.00  0.00
    7. 0.1   0.00  0.00  
    8. .....
    

    Bislang überlese ich die ersten drei Zeilen mit fgets. Das funktioniert auch ganz gut. Mit Deinem letzten Tip, sollte ich auch nun die Werte in Zeile 4. richtig einlesen können. Meine Frage bestand allerdings darin, wie ich sicherstelle, dass ich mit dem nächsten fscanf-Aufruf die Zahlenwerte der Zeile 5 einlese, denn die 5 in der Zeile 4 interessiert mich nicht mehr. So wie ich fscanf zurzeit verstehe wird der Pointer in der Datei einfach nur "weitergeschoben". Ergo, würde ich mit dem nächsten Aufruf von fscanf

    if (fscanf(stdptr, "%d %d %d", &i, &j &k) == 3) {
    // ....
    }
    

    die Werte 5 0.0 0.0 einlesen, anstatt 0.0 0.0 0.0!

    Wie würdest Du vorgehen? Meine Idee bestand darin soviele Einzelzeichen einzulesen, bis ich das Ende der Zeile '\n' erreicht habe. Würdest Du dazu eine eigene Funktion schreiben? Bin mit meinem Ansatz nicht so richtig zufrieden, da er in meinen Augen sehr unbeholfen erscheint....

    Gruß,

    W2K2005



  • Ich meinte, Du solltest einfach "fgets()" machen, um z.B. die "5" zu überlesen (einschließlich Zeilenumbruch).



  • Hi,

    angenommen ich habe 3 Werte mit fscanf eingelesen und die Zeile endet hier tatsächlich - würde fscanf mich dann nicht bereits in die nächste Zeile katapultieren, so dass ich die Werte dort nicht mehr mit fscanf erfassen kann ????

    231   11  21  1  5
    40    10  12  1
    

    Kannst Du mir noch einen Hinweis geben, wo ich nachlesen kann, wie man eine Funktion mit einer optionalen Parameterliste definiert? Ich möchte all die Infos, die Du mir hast zukommen lassen in einer Funktion verarbeiten, die den Einleseformalismus automatisch steuert!
    Hierzu wollte ich der Funktion eine Liste mit Paramtern übergeben - kein Feld!

    Gruß,

    W2K2005



  • Ich würde hier nicht mit fscanf arbeiten sondern nur mit fgets und dann die zeilen mit strtok und anderen hilfmitteln zerlegen... sscanf kann man dann immer noch aufrufen ...



  • W2K2005 schrieb:

    Hi,

    angenommen ich habe 3 Werte mit fscanf eingelesen und die Zeile endet hier tatsächlich - würde fscanf mich dann nicht bereits in die nächste Zeile katapultieren, so dass ich die Werte dort nicht mehr mit fscanf erfassen kann ????

    231   11  21  1  5
    40    10  12  1
    

    Kannst Du mir noch einen Hinweis geben, wo ich nachlesen kann, wie man eine Funktion mit einer optionalen Parameterliste definiert? Ich möchte all die Infos, die Du mir hast zukommen lassen in einer Funktion verarbeiten, die den Einleseformalismus automatisch steuert!
    Hierzu wollte ich der Funktion eine Liste mit Paramtern übergeben - kein Feld!

    Ich schrieb bereits, daß fscanf() dort stehen bleibt, wo der letzte Parameter gelesen wurde.

    Also, nimm mal folgende Zeilen an:

    231  11 21 1 5 
    40   10 12 1
    
    char buf[100];
    int a, b, c, d, e;
    fscanf( fp, "%d %d %d %d %d", &a, &b, &c, &d, &e ); /* liest 231 11 21 1 5 nach a b c d e */
    fscanf( fp, "%d %d %d %d", &a, &b, &c, &d );        /* liest 40 10 12 1 nach a b c d */
    rewind( fp ); /* zurück an den Anfang */
    fscanf( fp, "%*d %d %d %d %*d", &a, &b, &c );  /* ignoriert 231, liest 11 21 1 nach a b c, ignoriert 5 */
    fscanf( fp, "%*d %d %d %d", &a, &b, &c );  /* ignoriert 40, liest 10 12 1 nach a b c */
    rewind( fp ); /* zurück an den Anfang */
    fscanf( fp, "%*d %d %d %d ", &a, &b, &c ); /* ignoriert 231, liest 11 21 1 nach a b c, Dateizeiger steht jetzt auf "5" */
    fgets( buf, 100, fp );  /* liest "5\n" nach buf */
    fscanf( fp, "%s %d %d %d", buf, &a, &b, &c ); /* liest 40 10 12 1 nach buf a b c */
    

    Variable Argumentliste geht so:

    #include <stdarg.h>
    #include <stdio.h>
    
    void func( int anz, ... ) {
       va_list ap; int i;
       va_start( ap, anz );
       for ( i=0; i < anz; ++i ) {
          int a = va_arg( ap, int );
          printf( "arg %d = %d\n", i, a );
       }
       va_end( ap );
    }
    

Anmelden zum Antworten