简体   繁体   中英

saving file in arrays without malloc with c

I have a homework where i need to read from a file and save in arrays informations like the city name, the country code, the county name and the population

#include <stdio.h>
#include <string.h>

int main () 
{
    struct Country
    {
       char name [100];   // Le nom ASCII
       char code[100]; // Le code de deux lettres
   };

   //const struct Pays PAYS_BIDON = {"??", "??"};
   
   struct City
   {
       char name[100]; // Le nom ASCII
       long population;          // La population
       struct Country country;          // Le pays de la ville
   };
    struct City city;
    FILE* fp = fopen("fich.txt", "r");
 
    if (!fp)
    {
        printf("Can't open file\n");
    }
    else 
    {
        char buffer[1024];
        while (fgets(buffer, 1024, fp))
        {
            int i =0;
            char* value = strtok(buffer, "\t");
            while (value) 
            {
                strcpy(city.name,value);
                value = strtok(NULL, "\t");
                printf("name : %s\n", city.name);
              
            }
            
        }
        fclose(fp);
    }
    return 0;

} 

until here my code is working but when i try to read the country name it doesn't work:

#include <stdio.h>
#include <string.h>

int main () 
{
    struct Country
    {
       char name [100];   // Le nom ASCII
       char code[100]; // Le code de deux lettres
   };

   //const struct Pays PAYS_BIDON = {"??", "??"};
   
   struct City
   {
       char name[100]; // Le nom ASCII
       long population;          // La population
       struct Country country;          // Le pays de la ville
   };
    struct City city;
    FILE* fp = fopen("fich.txt", "r");
 
    if (!fp)
    {
        printf("Can't open file\n");
    }
    else 
    {
        char buffer[1024];
        while (fgets(buffer, 1024, fp))
        {
            int i =0;
            char* value = strtok(buffer, "\t");
            while (value) 
            {
                strcpy(city.name,value);
                value = strtok(NULL, "\t");
                printf("city name : %s\n", city.name);
                strcpy(city.country.name,value);
                value = strtok(NULL, "\t");
                printf("country : %s\n", city.country.name);
                
            }
            
        }
        fclose(fp);
    }
    return 0;

} 

the data in the file are like this:

3040051 les Escaldes    les Escaldes    Ehskal'des-Ehndzhordani,Escaldes,Escaldes-Engordany,Les Escaldes,esukarudesu=engorudani jiao qu,lai sai si ka er de-en ge er da,Эскальдес-Энджордани,エスカルデス=エンゴルダニ教区,萊塞斯卡爾德-恩戈爾達,萊塞斯卡爾德-恩戈爾達    42.50729    1.53414 P   PPLA    AD      08              15853       1033    Europe/Andorra  2008-10-15
3041563 Andorra la Vella    Andorra la Vella    ALV,Ando-la-Vyey,Andora,Andora la Vela,Andora la Velja,Andora lja Vehl'ja,Andoro Malnova,Andorra,Andorra Tuan,Andorra a Vella,Andorra la Biella,Andorra la Vella,Andorra la Vielha,Andorra-a-Velha,Andorra-la-Vel'ja,Andorra-la-Vielye,Andorre-la-Vieille,Andò-la-Vyèy,Andòrra la Vièlha,an dao er cheng,andolalabeya,andwra la fyla,Ανδόρρα,Андора ла Веля,Андора ла Веља,Андора ля Вэлья,Андорра-ла-Велья,אנדורה לה וולה,أندورا لا فيلا,አንዶራ ላ ቬላ,アンドラ・ラ・ヴェリャ,安道爾城,안도라라베야 42.50779    1.52109 P   PPLC    AD      07              20430       1037    Europe/Andorra  2020-03-03
290594  Umm Al Quwain City  Umm Al Quwain City  Oumm al Qaiwain,Oumm al Qaïwaïn,Um al Kawain,Um al Quweim,Umm Al Quwain City,Umm al Qaiwain,Umm al Qawain,Umm al Qaywayn,Umm al-Quwain,Umm-ehl'-Kajvajn,Yumul al Quwain,am alqywyn,mdynt am alqywyn,Умм-эль-Кайвайн,أم القيوين,مدينة ام القيوين 25.56473    55.55517    P   PPLA    AE      07              62747       2   Asia/Dubai  2019-10-24

i need from the first line

     city.name = les Escaldes ;
     city.country.code = AD;
     city.population = 15853;

i need from the second line

     city.name = Andorra la Vella;
     city.country.code = AE;
     city.population = 20430;

i need from the third line

     city.name = Umm Al Quwain City;
     city.country.code = AD;
     city.population = 62747;

so i don't know what the wrong thing i'm doing or the right thing to do

A few issues...

  1. You are using a single instance of your struct (eg) struct City city; . So, when you read the second line, your overwriting/trashing the data for the first.

  2. You need an array of structs.

  3. And, although it is legal, defining the structs at function scope isn't terribly useful. If you decided to split the function into multiple ones, the others wouldn't have the struct definition. Better to define them at file scope so all functions can use them.

  4. You're using both city.name and city->name . Only one is correct.

  5. The while (value) loop doesn't work as you would intend.

  6. Also, you're not filling in all fields of the structs.

Here's a refactored version:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

struct Country {
    char name[100];                 // Le nom ASCII
    char code[100];                 // Le code de deux lettres
};

struct City {
    char name[100];                 // Le nom ASCII
    long population;                // La population
    struct Country country;         // Le pays de la ville
};

// NOTE: need array of structs
struct City citylist[100];

int
main(void)
{
    struct City *city;

    FILE *fp = fopen("fich.txt", "r");
    if (! fp) {
        printf("Can't open file -- %s\n",strerror(errno));
        exit(1);
    }

    char buffer[1024];

    int count = 0;
    char *value;

    // load up file contents
    while (fgets(buffer, sizeof(buffer), fp)) {
        city = &citylist[count++];

        value = strtok(buffer, "\t\n");
        strcpy(city->name,value);

        value = strtok(NULL, "\t\n");
        city->population = atol(value);

        value = strtok(NULL, "\t\n");
        strcpy(city->country.name,value);

        value = strtok(NULL, "\t\n");
        strcpy(city->country.code,value);
    }

    fclose(fp);

    // print data
    for (int i = 0;  i < count;  ++i) {
        city = &citylist[i];
        printf("City: %s, population %ld, Country: %s (Code %s)\n",
            city->name,city->population,
            city->country.name,city->country.code);
    }

    return 0;
}

Note that I've defined an arbitrary fixed size array citylist . But, having a dynamic array is much more flexible. For an implementation of that, see my answer: Creation of Dynamic Array of Strings in C

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM