C анализ массива символов fgets() на несколько переменных с помощью sscanf с использованием структур

В этой программе она компилируется, но я получаю ошибку сегментации, sscanf(str, "%d %s %s %d %f", &pos, z[pos-1].city, z[pos-1].state, &z[pos-1].population, &z[pos-1].growth); потому что эта строка z[pos-1].city, z[pos-1].state не имеет &, но когда я добавляю это, я получаю предупреждение: format â%sâ expects type âchar *â, but argument 4 has type âchar (*)[200]â.

я уверен, что есть другой способ сделать это, мне нужно использовать структуру, прочитать информацию о хранилище файлов в массив структуры, а затем отобразить массив. printf работает, просто сохраняя город и штат в массив символов.

Я прокомментировал область, где я пытался инициализировать массив, и имел несовместимый тип со значением массива char все три: a, 'a', "a".

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

typedef struct{
    int rank;
    char city[200];
char state[50];
int population;
float growth;
}city_t;

void read_data(city_t *z)
{
    FILE *inp;
    inp = fopen("cities.dat", "r");
    char str[256];
    int pos = 0;
    if(inp==NULL)
    {
        printf("The input file does not exist\n");
    }
    else
    {
        /*reads and test until eof*/
        while(1)
        {
            /*if EOF break while loop*/
            if(feof(inp))
            {break;}
            else
            {
                /*read in a number into testNum*/
                //fscanf(inp, "%d", &testNum);
                fgets(str,sizeof(str),inp);
                sscanf(str, "%d %s %s %d %f", &pos, z[pos-1].city, z[pos-1].state, &z[pos-1].population, &z[pos-1].growth);
                z[pos-1].rank = pos;
            }
        }
    }
    fclose(inp);
}

void print_data(city_t *z, int size)
{
    int i;
    printf("rank\tcity\t\tstate\tpopulation\t\tgrowth\n");
    for(i=0;i<size;i++)
    {
        printf("%d\t%s\t\t%s\t\%d\t\t%f\n", z[i].rank, z[i].city, z[i].state, z[i].population, z[i].growth);
    }
}

int main()
{
    int i;
    city_t cities[10];
    /*for(i;i<10;i++)
    {
        cities[i].rank = 0;
        cities[i].city = "a";
        cities[i].state = "a";
        cities[i].population = 0;
        cities[i].growth = 0.00;
    }*/
    read_data(&cities[0]);
    print_data(&cities[0], 10);
    return(0);
}

{
dat file
1 New_York NY 8143197 9.4
2 Los_Angeles CA 3844829 6.0
3 Chicago IL 2842518 4.0
4 Houston TX 2016582 19.8
5 Philadelphia PA 1463281 -4.3
6 Phoenix AZ 1461575 34.3
7 San_Antonio TX 1256509 22.3
8 San_Diego CA 1255540 10.2
9 Dallas TX 1213825 18.0
10 San_Jose CA 912332 14.4
}

person user1834476    schedule 19.11.2012    source источник


Ответы (1)


В read_data вы сканируете z[pos-1]...., где pos начинается с 0. Таким образом, вы будете писать за пределами (до) расширения массива.

Просто выполните глобальную замену pos-1 на pos, а также увеличьте pos; вы также можете использовать fscanf, поэтому ваше чтение может быть:

 for (int pos=0; !feof(inp); ++pos)
 {
     fscanf(inp, "%d %s %s %d %f",
            &z[pos].rank,
            z[pos].city,
            z[pos].state,
            &z[pos].population,
            &z[pos].growth);
 }
person William Morris    schedule 19.11.2012
comment
спасибо, это было действительно простое исправление, на которое я потратил слишком много времени :) - person user1834476; 20.11.2012