2016-02-16 4 views
0

Итак, у меня была эта проблема, которую я пытался решить в течение примерно 8 часов ... Я отказался от поиска ответа без посторонней помощи. Я пробовал использовать realloc() и malloc() соответственно, поэтому любой вход был бы замечательным!правильное распределение памяти для строк

Цель этого существа в C состоит в том, чтобы разрешить создание «карты», позже я буду использовать ncurses для создания карты.

вход из файла выглядит следующим образом

10X16 de4 dw9 ds8 g8,7 m3,4 h6,5 p2,2 
6X20 dn5 ds4 W4,3 e2,12 M1,1 
10X13 ds3 dw9 
10X12 
5X4 
6x12 

Вот код:

char *importLevel() 
{ 
    FILE *fPointer; 
    fPointer = fopen("Level", "r"); //Opens text file to read 
    char* rooms[150];// set up for memory allocation 
    char commands[150];// set up for pulling data from read file 

    while (!feof(fPointer)) 
    { 
     fgets(commands,150, fPointer); // this takes each line from the file 
    } 

    *rooms = (char *) malloc(150 * sizeof(char)); // memory allocation 
    for (int i = 0; i < 150; i++) 
    { 
     if (rooms[i] != NULL) 
     { 
      *rooms[i] = commands[i]; // supposed to give rooms the string 
     } 
    } 

    fclose(fPointer);// close file 

    return *rooms; // return pointer 
} 

Я надеюсь, что я не так глуп, как я чувствую прямо сейчас! Спасибо :)

Изменить: Я так глуп, как я чувствовал себя хорошо, то

+0

Ваш код вздор. Итак, сначала вам нужно будет объяснить, как вы хотите в этом коде. – BLUEPIXY

+0

sorry @BLUEPIXY Im new here – Blueshadoe

+0

Вы, кажется, новичок в C, также. Вам нужно будет предоставить * много больше контекста, например ... что должен делать этот код? Каков формат вашего ввода? почему вы используете C для решения этой проблемы? и т. д. –

ответ

0

Другие указали некоторые изменения, которые вам нужно внести. Итак, посмотрите, что они сказали, и сравните свою версию с приведенной ниже. Это должно помочь.

Вот исправленная версия вашей программы.Я должен был догадаться, некоторые из ваших намерений, на основе коды и данных [пожалуйста, простите безвозмездную ыборку стиля]:

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

char ** 
importLevel() 
{ 
    FILE *fPointer; 
    char commands[150];     // file line buffer 
    int roomcnt = 0; 
    char *cp; 
    char *bp; 
    char **rooms = NULL;    // set up for memory allocation 

    fPointer = fopen("Level", "r");  // Opens text file to read 
    if (fPointer == NULL) { 
     printf("importLevel: unable to open file -- %s\n",strerror(errno)); 
     exit(1); 
    } 

    while (1) { 
     // this takes each line from the file 
     cp = fgets(commands, sizeof(commands), fPointer); 
     if (cp == NULL) 
      break; 

     // setup buffer for strtok 
     bp = commands; 

     // parse all words on line 
     while (1) { 
      // NOTE: the first assumes you want "g8,7" within a room 
      // the second assumes you want "g8,7" as two separate rooms 
#if 1 
      cp = strtok(bp," \n"); 
#else 
      cp = strtok(bp," ,\n"); 
#endif 

      // strtok wants this on 2nd and subsequent loops for this line 
      bp = NULL; 

      // bug out if no more words on this line 
      if (cp == NULL) 
       break; 

      // increase room list size (allow space for terminator) 
      // NOTE: rooms will be preserved when we return from this function 
      rooms = realloc(rooms,sizeof(char *) * (roomcnt + 2)); 

      // NOTE: cp is pointing to something in our stack frame that 
      // will go away when we return or when we read the next line 
      // so we must preserve it in the heap now 
      cp = strdup(cp); 

      // add the contents of the room 
      rooms[roomcnt] = cp; 

      // advance count of number of rooms 
      ++roomcnt; 
     } 
    } 

    // add terminator to list 
    if (rooms != NULL) 
     rooms[roomcnt] = NULL; 

    fclose(fPointer);     // close file 

    return rooms;      // return pointer 
} 

P.S. Не чувствую себя плохо. Независимо от того, насколько опытен программист, мы все делаем «немые» ошибки. И мы делаем их каждый день. Добро пожаловать в клуб!

1

Есть довольно много вещей, чтобы адрес.

while (!feof(fPointer)) 
{ 
    fgets(commands,150, fPointer); // this takes each line from the file 
} 

Это будет перезаписывать данные в commands каждый раз через петлю. Когда петля выйдет, вы будете читать и отбрасывать все данные, кроме последней строки. Вы захотите либо использовать 2-мерный массив, либо, скорее всего, сохранить данные в rooms во время чтения. Второй способ быстрее и использует меньше памяти.

*rooms = (char *) malloc(150 * sizeof(char)); 

Такое похоже, что вы пытаетесь создать 2-й массив. Вместо этого вы хотите сделать что-то вроде этого:

for (int ii = 0; ii < 150; ++ii) 
    rooms[ii] = malloc(150 * sizeof(char)); 

Обратите внимание, что этот malloc не инициализирует память. Таким образом, ваш чек

if (rooms[i] != NULL) 

Собираюсь дать вам неточные результаты. Содержимое rooms[i] не определено. Если вы хотите инициализировать массив для всех нулей, попробуйте использовать memset.

Тогда:

*rooms[i] = commands[i]; 

Не собирается копировать данные из commands, а он будет копировать только первый символ из commands. Чтобы скопировать всю строку, вы должны использовать strcpy или strncpy, чтобы избежать возможных проблем с переполнением буфера. memcpy также является возможностью скопировать некоторое количество байтов вместо C-строк с нулевым завершением.

И наконец, возвращение *rooms - это ошибка, ожидающая своего появления. Вам лучше было бы передать rooms в качестве параметра и выделить в него. См. Allocate memory 2d array in function C, как это сделать.

+1

'strndup' является еще одним хорошим здесь, чтобы получить« malloc' и 'strncpy» в один выстрел. – ash