txt zeilenweise auslesen und in Variablen speichern



  • Hallo Leute,

    ich hab eine txt in der Länder, Kontinente und Bevölkerungsanzahlen drin stehen.

    China
    Asien
    1330.141

    Indien
    Asien
    1173.108

    USA
    Nord-Amerika
    310.298

    Ich brauche ein Schleife, in der ich jeweils immer Land in char d[30], Kontinent in char d[30] und Anzahl in int anzahl einlese. Danach wird das ganze in eine Liste sortiert. Die Sortierung habe ich auch schon fertig. Nur dieses zeilenweise Auslesen aus der txt bekomme ich nicht hin. Kann mir da vielleicht mal jemand ein Beispiel zeigen?
    [ Nachricht wurde editiert von psigh am 04.02.2011 14:43:31 ]



  • Einfacher wäre es, wenn ein Datensatz komplett in EINER Zeile stehen würde. Reicht dir das?



  • Also ich muss das nehmen, was wir an Material bekommen haben. Und das sieht so aus.

    Mein ganzer Code ist dieser

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct Knot* Liste;
    
    typedef struct
        {
            char Name[30];
            char Kontinent[30];
            double Einwohner; /*Einwohner in Millionen*/
    
        }Land;
    
    typedef struct Knot
        {
            Land eintrag;
            Liste vorgaenger;
            Liste nachfolger;
        }Knoten;
    
    typedef struct
        {
            Liste anfang;
            Liste ende;
        }anfang_ende_liste;
    
    void einfuegen(anfang_ende_liste* liste, char* c, char* d, double anzahl){
    Liste suche;
    int a=0;
    
        if(liste->anfang==NULL){
            Liste tmp=(Liste) malloc(1*sizeof(Knoten));
            liste->anfang=tmp;
            liste->ende=tmp;
            liste->anfang->nachfolger=NULL;
            liste->anfang->vorgaenger=NULL;
            strcpy(tmp->eintrag.Name, c);
            strcpy(tmp->eintrag.Kontinent, d);
            tmp->eintrag.Einwohner=anzahl;
            a=1;
        }
    
        else {
            suche=(liste->anfang);
    
            while(suche!=NULL){
    
                if (strcmp(suche->eintrag.Name,c)<0){
                    Liste tmp=(Liste) malloc(sizeof(Knoten));
                    tmp->eintrag.Einwohner=anzahl;
                    strcpy(tmp->eintrag.Name,c);
                     strcpy(tmp->eintrag.Kontinent, d);
    
                    if(suche->nachfolger!=NULL && suche->vorgaenger!=NULL){
                        tmp->nachfolger=suche->nachfolger;
                        suche->nachfolger=tmp;
                        tmp->vorgaenger=suche;
                        tmp->nachfolger->vorgaenger=tmp;
                        a=1;
                    }
    
                    else if(suche->nachfolger==NULL){
                        tmp->nachfolger=NULL;
                        tmp->vorgaenger=suche;
                        suche->nachfolger=tmp;
                        liste->ende=tmp;
                        a=1;
                    }
    
                }
    
            suche=suche->nachfolger;
    
            }
        }
    
        if(a==0){
    
            Liste tmp=(Liste) malloc(sizeof(Knoten));
            tmp->eintrag.Einwohner=anzahl;
            strcpy(tmp->eintrag.Name,c);
            strcpy(tmp->eintrag.Kontinent, d);
            tmp->nachfolger=liste->anfang;
            tmp->vorgaenger=NULL;
            liste->anfang=tmp;
            tmp->nachfolger->vorgaenger=tmp;
        }
    
    }
    
    void ausgeben(anfang_ende_liste liste){
    
        Liste tmp=liste.anfang;
        printf("\n\n\n");
        while (tmp!=0){
            printf("Land:%s\nKontinent:%s\nEinwohnerzahl:%d\n\n", tmp->eintrag.Name,tmp->eintrag.Kontinent, tmp->eintrag.Einwohner);
            tmp=tmp->nachfolger;
    
        }
    }
    
    int main(void){
    
    char c[30];
    char d[30];
    double anzahl;
    anfang_ende_liste liste={0};
    
    FILE *fil; 
    fil=fopen("laender.txt","r")
    
    while(feof(fil)=0){
    
    einfuegen(&liste,c,d,anzahl);}
    }
    
    ausgeben(liste);
    
    return 0;
    }
    

    Alles ist fertig. Ich muss nur in main jetzt immer die "Blöcke" in die Variablen reinbekommen. Also erster Block ist

    China ---> in char[c]
    Asien ---> in char[d]
    1330.141-->in anzahl

    das dann einfach in die funktion "einfuegen" (klappt)

    und weiter ->nächster Block



  • Ich verstehe die txt auch nicht richtig. Ich hab mal zum Test vorlgendes geschrieben:

    int main(void){
    
    char c[30];
    char d[30];
    double anzahl;
    anfang_ende_liste liste={0};
    
    FILE *fil;
    fil=fopen("laender.txt","r");
    
    while(!feof(fil)){
    
      fscanf(fil, "%s", d);
      if (!feof(fil)) 
         printf("%s", d);
    
    }
    return 0;
    }
    

    Also einfach nur jede Zeile bis zum Ende Anzeigen. Das sieht dann so aus. In meiner txt werden aber doch Leerzeilen angezeigt...?

    ChinaAsien1330.141IndienAsien1173.108USANord-Amerika310.233IndonesienAsien242.96
    8BrasilienSued-Amerika201.103PakistanAsien184.405BangladeschAsien156.118NigeriaA
    frika152.217RusslandEuropa/Asien139.390JapanAsien126.804MexicoNord-Amerika112.46
    9PhilippinenAsien99.900VietnamAsien89.571AethiopienAfrika88.013DeutschlandEuropa
    82.283AegyptenAfrika80.472TuerkeiAsien/Europa77.804IranAsien76.923DR-KongoAfrika
    70.916ThailandAsien



  • int leseDatensatz(FILE *f,char *a,char *b,double *c)
    {
      char zeile[80];
      void *q[]={a,b,c},**p=&q[-1];
      while( fgets( zeile,80,f ) && *zeile!='\n' && *p++!=c )
        sscanf(zeile,*p==c?"%lf":"%s",*p);
      return *p==c;
    }
    

    Aufruf dann etwa:

    while( leseDatensatz(fil,c,d,&anzahl) )
      einfuegen(&liste,c,d,anzahl);
    


  • Vielen Dank für die Antwort.

    Ich habsm ehrlich gesagt, noch nicht berstanden. Ich versuche mal durchzusteigen.



  • Also erstmal vielen Dank NOCHMALS. Denn er tut etwas. Die Liste ist jetzt falsch dortiert, aber ich werde schon rausfinden, wieso.



  • Ne.. mit der Einfüghen-Funktion stimt auch was nicht. Muss ich nochmal schauen



  • Endlich. Es klappt

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct Knot* Liste;
    
    typedef struct
        {
            char Name[30];
            char Kontinent[30];
            double Einwohner; /*Einwohner in Millionen*/
    
        }Land;
    
    typedef struct Knot
        {
            Land eintrag;
            Liste vorgaenger;
            Liste nachfolger;
        }Knoten;
    
    typedef struct
        {
            Liste anfang;
            Liste ende;
        }anfang_ende_liste;
    
    int leseDatensatz(FILE *f,char *a,char *b,double *c)
    {
      char zeile[80];
      void *q[]={a,b,c},**p=&q[-1];
      while( fgets( zeile,80,f ) && *zeile!='\n' && *p++!=c )
        sscanf(zeile,*p==c?"%lf":"%s",*p);
      return *p==c;
    
    }
    
    void einfuegen(anfang_ende_liste* liste, char* c, char* d, double anzahl){
    Liste suche;
    int a=0;
    
        if(liste->anfang==NULL){
            Liste tmp=(Liste) malloc(1*sizeof(Knoten));
            liste->anfang=tmp;
            liste->ende=tmp;
            liste->anfang->nachfolger=NULL;
            liste->anfang->vorgaenger=NULL;
            strcpy(tmp->eintrag.Name, c);
            strcpy(tmp->eintrag.Kontinent, d);
            tmp->eintrag.Einwohner=anzahl;
            a=1;
        }
    
        else {
            suche=(liste->anfang);
    
            while(suche!=liste->ende){
    
                if ((strcmp(suche->eintrag.Name,c)<0)&&(strcmp(suche->nachfolger->eintrag.Name,c)>0)){
                    Liste tmp=(Liste) malloc(sizeof(Knoten));
                    tmp->eintrag.Einwohner=anzahl;
                    strcpy(tmp->eintrag.Name,c);
                    strcpy(tmp->eintrag.Kontinent, d);
                    tmp->nachfolger=suche->nachfolger;
                    suche->nachfolger=tmp;
                    tmp->vorgaenger=suche;
                    tmp->nachfolger->vorgaenger=tmp;
                    a=1;
                    break;
                    }
    
            suche=suche->nachfolger;
    
            }
       }
    
        if(a==0){
    
            Liste tmp=(Liste) malloc(sizeof(Knoten));
            tmp->eintrag.Einwohner=anzahl;
            strcpy(tmp->eintrag.Name,c);
            strcpy(tmp->eintrag.Kontinent,d);
    
                if(strcmp(liste->ende->eintrag.Name,c)<0){
                    tmp->nachfolger=NULL;
                    tmp->vorgaenger=liste->ende;
                    tmp->vorgaenger->nachfolger=tmp;
                    liste->ende=tmp;
                }
    
                else{
                tmp->nachfolger=liste->anfang;
                liste->anfang=tmp;
                tmp->vorgaenger=NULL;
                tmp->nachfolger->vorgaenger=tmp;
    
                }
    
        }
    
    }
    
    void ausgeben(anfang_ende_liste liste){
    
        Liste tmp=liste.anfang;
        printf("\n\n\n");
        while (tmp!=0){
            printf("Land:%s\nKontinent:%s\nEinwohnerzahl:%lf\n\n", tmp->eintrag.Name,tmp->eintrag.Kontinent, tmp->eintrag.Einwohner);
            tmp=tmp->nachfolger;
    
        }
    }
    
    int main(void){
    
    char c[30];
    char d[30];
    FILE *fil;
    double anzahl;
    anfang_ende_liste liste={0};
    fil=fopen("laender.txt","r");
    
    while( leseDatensatz(fil,c,d,&anzahl)){
        einfuegen(&liste,c,d,anzahl);
         }
    
    ausgeben(liste);
    
    return 0;
    }
    

    Könntest Du mir dieses vielleicht einmal erklären?

    int leseDatensatz(FILE *f,char *a,char *b,double *c)
    {
      char zeile[80];
      void *q[]={a,b,c},**p=&q[-1];
      while( fgets( zeile,80,f ) && *zeile!='\n' && *p++!=c )
        sscanf(zeile,*p==c?"%lf":"%s",*p);
      return *p==c;
    
    }
    

    Das hab ich noch nicht verstanden.

    Vielen Dank,

    Dominik



  • Ich wollte nochmal darum bitten, dass mir jemand vielleicht ganz kurz erläutert, wie diese Funktion arbeitet.

    Besonders das hier

    sscanf(zeile,  *p == c ? "%lf" : "%s",  *p);
    

    macht mir starke Probleme. Blöder Weise konnte mir das auch keine meiner Kommilitonen erklären.



  • Der Prototyp von sscanf ist :

    int sscanf ( const char * str, const char * format, ...);
    

    sscanf erwartet also einen str in den die Daten geschrieben werden,
    einen Formatstring und noch eine beliebige Anzahl von Parametern Parameter(...).

    Bei sscanf(zeile, *p == c ? "%lf" : "%s", *p); entspricht
    zeile dem str, *p == c ? "%lf" : "%s" dem format und *p dem ...

    Bei *p == c ? "%lf" : "%s" siehst du den ?: Operator.

    Allgemein geht der so: Bedingung ? WahrWert : FalschWert

    Wenn die Bedingung wahr ist nimm den WahrWert, sonst den FalschWert.

    Zusammen:
    Wenn der Wert auf den p Zeigt gleich c ist, dann nimm als Formatstring "%lf" (ein double), sonst "%s" (ein String) und schreibe das in zeile.


Anmelden zum Antworten