werte aus datei auslesen



  • hallo,
    ich habe eine ca 2000 seitige textdatei.In dieser sind informationen = koordinaten (x,y,z) zu atomen enthalten, die ich spaeter fuer eine rechnung brauche. Das oeffnen und lesen und ausgeben der datei auf dem bildschirm ist kein problem.
    mein problem liegt darin, den anfang des lesevorgangs in der datei festzulegen, <startwort> danach lesen bis <endwort> und mein zweites problEm liegt darin dass ich die werte nicht fuer meine rechnung auslesen (oder speichern) kann. trotz jeglichen versuches stehen sie mir jedesmal in der rechnung nicht zur verfuegung.
    ➡ Beispiel
    die datei sieht so aus (ausschnitt..leider sind es mehrere seiten letztendlich...)

    REMARK 3 B11 (A2) : NULL
    REMARK 3 B22 (A
    2) : NULL
    REMARK 3 B33 (A2) : NULL
    REMARK 3 B12 (A
    2) : NULL
    HETATM 9414 O HOH 226 43.926 92.547 75.796 1.00 32.58 O
    HETATM 9415 O HOH 227 41.196 91.524 75.241 1.00 40.08 O
    HETATM 9416 O HOH 228 41.925 93.868 88.691 1.00 15.39 O
    HETATM 9417 C HOH 229 36.554 98.289 85.574 1.00 22.68 O
    HETATM 9418 O HOH 230 38.344 104.475 89.670 1.00 17.92 O
    .
    .
    .
    HETATM 9424 O HOH 236 29.186 109.801 88.763 1.00 9.92 O
    HETATM 9425 O HOH 237 28.397 97.067 91.471 1.00 14.86 O
    REMARK 290 REMARK: NULL
    REMARK 295

    das dateieinlesen soll bei HETATM starten und bei der letzten zeile mit HETATM auch wieder stoppen
    dazwischen:
    die erste spalte moechte ich lesen und zugriffsbereit speichern,
    sie dritte spalte sind die atomnamen und die 6te, die 7te, und die 8te spalte sind die koordinaten(x,y,z) zu in der in der 3 spalte gegebenen atome(namen).
    in der rechnung werden die abstaende aller aufgelisteten atome bestimmt --> es ist in schleife die (vereinfachte) rechnung ➡ A=(xi-xj)+(yi-yj)(zi-zj) durchzufuehren. i und j sind die atomeindizes der atome von denen durchlaufend von allen untereinander jeweils der abstand bestimmt werden soll

    ➡ 😕 ➡ WIE ZUR HOELLE KRIEG ICH DAS ALLES VON DER KOLONNE IN VARIABLEN, DIE ICH IN DER RECHNUNG VERWENDEN WILL

    BITTE UM HILFE
    BIN AM KAPITULIEREN...



  • Stichwort: dynamische Speicherreservierung

    Für den Rest würde ich folgende Funktionen vorschlagen:
    fgets() -> Zeile einlesen
    strncmp() -> vergleicht Strings (z. B. HETATM ;))
    sscanf() -> liest aus einem String formatiert ein

    Für die Speicherung deiner Daten wär wohl eine Struktur ganz gut 😉



  • Die hier diskutierten Funktione substr, und StrRmLe können dabei vielleicht helfen http://www.c-plusplus.net/forum/viewtopic.php?t=73518

    Grober Abriß des Ablaufs

    int HETATM_gefunden=0;
    while (fgets(buffer,....)
    {
      substr(buffer,buffer1,' ');
      if (0==strcmpi(buffer1,"HETATM"))
       {
       HETATM_gefunden=1;
     //  zerlegen und in Strukt speichern
       }
    else
     { 
      if (1==HETATM_gefunden)
      { 
      Mathematik
      }
       HETATM_gefunden=0;
     }
    }
    

    Ich hoffe es hilft 🙂



  • ok alles klar!
    ➡ haenge aber immer noch an der struktur fuer die speicherung meiner daten...
    "er" erkennt sie in der rechnung nicht an und verschiebt alles irgendwie wenn ich versuche die koordinaten fuer die rechnung in der form mit x, y, z zu speichern
    ➡ 😕 ➡ nun vielleicht sitz ich auch schrecklich auf der leitung



  • Zeig mal den Aufbau deiner Struktur und dein sscanf() bzw. fscanf() (oder was du zum auslesen hergenommen hast der einzelnen Daten)



  • oje ok jetzt wirds peinlich
    aber gut hoffe nur ich quaele nicht
    da sind naemlich sicher ziemlich fehler drin 😕

    struct coordinates
    {
    char start[20];
    int number;
    char name[4];
    double x;
    double y;
    double z;
    } coordinateslist;
    int catFcoordchar(char *fcoordinates
    {int HETATM_found=0;
    FILE *inF=NULL;
    inF=fopern(fcoordinates, "r");

    char buffer;
    char bufferl;

    inf(!inF)
    {return -1;}

    while (NULL!=fgets(&buffer, bufferl, inF))
    {substr(buffer, bufferl,HETATM);
    if (strstr (&buffer, "HETATM")!=NULL)

    HETATM_found=1:
    //zerlegen und in struct speichern ???versuch?? aber wie weise ich da den kolonnen das //durchlaufende x und y und z zu?? versteh s nicht??
    fscanf (inF, "%s", &coordinateslist.start); print f("\n %s"coordinateslist.start);
    fscanf (inF, "%lg", &coordinateslist.number); print f("\n %lg"coordinateslist.number);
    ...

    } else....

    int main (void)

    {
    if(catFcoordChar("coordinates.pdb"))

    {
    ...
    }return 0;
    }



  • Alles klar, ich seh schon wo der Fehler ist.

    Also am besten definierst du deine Struktur so, wie die Daten in deiner Datei auch sind. Auch wenn du dabei Daten darin speicherst, die überflüssig sind.

    Also:

    typedef struct
    {
       char start[10];
       int nummer5; //sollte durch richtigen Namen ersetzt werden
       char zeichen; //sollte durch richtigen Namen ersetzt werden
       char wort[4]; //sollte durch richtigen Namen ersetzt werden
       int nummer3; //sollte durch richtigen Namen ersetzt werden
       double x;
       double y;
       double z;
       double faktor; //sollte durch richtigen Namen ersetzt werden
       double grad; //sollte durch richtigen Namen ersetzt werden
       char endzeichen; //sollte durch richtigen Namen ersetzt werden
    }coordinates;
    

    So und nun zum Einlesen. Da du ja schon die komplette Zeile mit fgets() einliest, darfst du danach nicht fscanf() verwenden. Du hast ja schon alles in buffer drinstehen. Daher wertest du also einfach den Inhalt von buffer aus. Und zwar folgendermaßen:

    ...
    coordinates *coordinateslist;
    int anzcoords=0;
    ...
    //ab hier in der Einleseschleife
    coordinateslist = realloc(coordinateslist, (anzcoords + 1) * sizeof(coordinates));
    ...
    sscanf(buffer, "%s %d %c %s %i %lf %lf %lf %lf %lf %c",
                    coordinateslist[anzcoords].start,
                   &coordinateslist[anzcoords].nummer5,
                   &coordinateslist[anzcoords].zeichen,
                    coordinateslist[anzcoords].wort,
                   &coordinateslist[anzcoords].nummer3,
                   &coordinateslist[anzcoords].x,
                   &coordinateslist[anzcoords].y,
                   &coordinateslist[anzcoords].z,
                   &coordinateslist[anzcoords].faktor,
                   &coordinateslist[anzcoords].grad,
                   &coordinateslist[anzcoords].endzeichen );
    ...
    ++anzcoords;
    ...
    


  • Kann der Lösung von AJ nur zustimmen.

    Aus schlechter Erfahrung heraus - beim konvertieren mit ..scanf mit langen Parameterlisten, typischerweise war das ...scanf korrekt aber die Inputdatei nicht konsistent in der Formatierung - bin ich davon abgekommen,

    - lese mit fgets
    - zerlege den Inputstring (substr & StrRmLe)
    - prüfe auf Gutmütigkeit z.b strlen() != 0
    - konvertiere die Einzelteile mit strtod und strtol
    - prüfe das Konveriertungsergebnis.

    Seitdem deutlich weniger Programmabstürze, leider etwas aufwendiger in der Programmierung.



  • hey danke klappt alles gut
    nur die letzte funktion laeuft irgendwie nicht
    [cpp]coordinateslist = realloc...
    da weigert er sich einen void* in coordinates* umzuwandeln...



  • Hallo,

    dann sage "ihm", daß du das trotzdem willst (und weißt, was du tust):

    [cpp]
    coordinateslist = (coordinates)* realloc(coordinateslist, (anzcoords + 1) * sizeof(coordinates));
    [/cpp]

    MfG


Anmelden zum Antworten