Как заполнить массив строками в C? - PullRequest
2 голосов
/ 20 февраля 2010

Я пытаюсь заполнить массив именами из файла:

Andrew
Andy
Bob
Dan
Derek
Joe
Pete
Richy
Steve
Tyler

Вот функция, которую я написал ... но при запуске программы происходит сбой:

#include <stdio.h>

main(){
  int i=0, size=10;
  char fname[15];
  char** data;
  char* name;
  FILE* fp;

  printf("Enter a filename to read names:\n");
  scanf("%s", fname);

  fp = fopen(fname, "r");
  if(fp == NULL)
    exit();

  data = (char**)malloc(sizeof(char**)*size);

  while(!feof(fp)){
    fscanf(fp, "%s", name);
    data[i] = (char*)malloc(sizeof(name));
    data[i] = name;
    i++;
  }

  fclose(fp);

  printf("\n\n");

  for(i=0; i<size; i++)
    printf("%s ", data[i]);

  free(data);
}

Кто-нибудь знает, что я делаю не так? Спасибо

Ответы [ 3 ]

5 голосов
/ 20 февраля 2010

У вас есть пара ошибок:

1) Вы никогда не выделяете память, где будет храниться name.Вы можете обойти это просто используя:

char name[128];

Тогда, когда вы используете fscanf , вы получите:

fscanf(fp, "%127s", name); // stores this in name correctly, now...

2) Выненадлежащим образом выделяется место для data[i]:

data[i] = (char*)malloc(sizeof(name));

Это выделит место для хранения одного указателя на символ (char*), поскольку name является char*.Вам нужно сделать:

data[i] = (char*)malloc(sizeof(char) * (strlen(name) + 1 ) );

Это выделит достаточно места для данных плюс один завершающий символ.

3) Вы неправильно назначаете data[i].Вы не можете просто использовать = здесь, но вам нужно использовать strcpy :

strcpy(data[i], name);

4) Вы не освобождаете отдельные указатели в элементах data[..].Вы должны добавить после своего printf бесплатный:

for(i=0; i<size; i++)
{
    printf("%s ", data[i]);
    free(data[i]);  // Free each pointer you allocate
}

Каждый malloc звонок должен в конечном итоге иметь соответствующий free звонок.

5 голосов
/ 20 февраля 2010

Вы никогда не выделяете место для имени. Но вы помещаете вещи в эту строку:

 fscanf(fp, "%s", name);

изменение

 char name[100];

и

fscanf(fp, "%99s", name);

Вы должны ограничить также имя файла:

scanf("%14s", fname);

также вы никогда не освобождаете данные для каждого элемента массива, если бы это была подпрограмма в более крупной системе, это привело бы к утечке памяти.

0 голосов
/ 20 февраля 2010

Есть довольно много проблем. Другой ответ говорит о том, что имя не инициализируется, поэтому я не буду повторять это.

Вторая проблема заключается в том, что вы неправильно обрабатываете EOF. feof вернет true только после того, как вы попытаетесь прочитать сразу за концом файла. Таким образом, вы получите пустое 11-е имя.

Последняя проблема заключается в том, что массив данных может содержать только 10 имен. Из-за второй проблемы вы переполните буфер пустым 11-м именем. Кроме того, ваш код зависит от деталей входного файла - дайте ему другой входной файл с большим количеством имен, и вы все равно будете падать даже после устранения проблемы 2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...