2015-04-06 3 views
0

Я пытаюсь прочитать файл из 10 строк различной длины (который не должен превышать 349 символов) и хранить их в динамически распределенном массиве, чтобы иметь возможность манипулировать ими позже. У меня есть код ниже, который дает мне «предупреждение: передающий аргумент 1 из âstrcpyâ делает указатель из целого без трансляции».Динамическое выделение строк из stdin?

Что я здесь сделал неправильно? Моя логика заключалась в том, что адреса должны быть указателем на массив указателей, где каждый указатель в массиве указывает на строку в строке, которую я попытаюсь выполнить, используя strcpy этой строки для этой точки.

char buffer[350]; 
    char** addresses; 
    int i = 0; 

    *addresses = malloc(sizeof(char*)*10); /* Let's start off with 10 addresses */ 

    while(fgets(buffer, sizeof(buffer), stdin) != NULL) 
    { 
      strcpy(*addresses[i],buffer); 
      i++; 
    } 

ответ

2

У вас есть пара вопросов:

  1. Синтаксис:

    Использование

    strcpy(addresses[i],buffer); 
    

    вместо

    strcpy(*addresses[i],buffer); 
    
  2. Память:

    Перед тем, как скопировать содержимое buffer, необходимо выделить память для addresses[i].

    Добавить строку для выделения памяти для addresses[i] перед вызовом strcpy.

    addresses[i] = malloc(sizeof(buffer)); 
    
1

Вы должны дать, как это,

strcpy(addresses[i],buffer); 

Если вы даете, как это,

strcpy(*addresses[i],buffer); 

Первый аргумент будет рассматривать как один символ.

И при выделении памяти вы должны сделать так,

address=malloc(sizeof(char)*10); 

Вы должны выделить память для каждого указателя.

address[i]=malloc(strlen(buffer)+1); 

Или же, вы можете использовать strdup функцию, которая будет выделять память для данной длины строки.

address[i]=strdup(buffer); 

strdup() возвращает указатель на новую строку, которая является дубликатом строки с. Память для новой строки получается с помощью malloc (3) и может быть освобождена со свободной (3).

+0

Так было использовано «* addresses = malloc (sizeof (char *) * 10);» правильно или должны ли они быть адресами? – Hazim

+0

@ Хэзим в конечном итоге до * одиннадцати * распределений. Один для последовательности из 10 указателей, затем еще 10 для каждого указателя для ссылки на * свой собственный * динамический буфер, который будет заполнен вашими данными линии для этого слота. Вы забыли последние распределения и, таким образом, вызывают * неопределенное поведение *. – WhozCraig

1

addresses является указателем на указатель, так что вам нужно выделить память для ваших указателей первой, а затем выделить память для каждых указателей по отдельности, как показано ниже.

В 2D-пространстве, если addresses является указателем на указатель, тогда addresses[i] является указателем. Для этого выделите память перед записью в это место.

char** addresses; 

    addresses = malloc(sizeof(char*)*10);// Now you 10 character pointers 
    int i = 0; 
    while(fgets(buffer, sizeof(buffer), stdin) != NULL) 
    { 
     size_t n = strlen(buffer); 
     if(n>0 && buffer[n-1] == '\n') 
     buffer[n-1] = '\0'; 
     if(i>=10) 
     break; 
     addresses[i] = malloc(strlen(buffer)+1);//Allocate memory to the pointer before writing to it 
     strcpy(addresses[i],buffer); 
     i++; 
    } 

PS: fgets() поставляется с новой строки, так что я добавил чек, чтобы заменить символ новой строки с нулем.

1

Чтобы быстро устранить ошибки, которые я вижу здесь:

  • Вы разыменования addresses (например *addresses или addresses[0].) Без обеспечения того, чтобы addresses точки где-то действует. Вы должны назначить addresses перед разыменованием.
  • Тип *addresses[i] в strcpy(*addresses[i],buffer): char, где ожидается, что это будет char *. Об этом жалуется ваш компилятор. Я подозреваю, что вы имели в виду strcpy(addresses[i], buffer).

Даже если вы хотите запустить этот код во встроенной среде, ваши требования кажутся достаточно простыми, что вам не нужно malloc. Фактически, введение malloc усложняет вещи ... Я стараюсь избегать этого, если это абсолютно необходимо. Вместо этого используйте автоматическую продолжительность хранения. Это сделает жизнь проще, потому что у вас не будет столько ошибочных ситуаций для обработки (хотя, как это вы все равно не обращаться с ними) ...

#define nelem(array) (sizeof array/sizeof *array) /* number of elements in array */ 

int main(void) 
{ 
    char address[10][351] = { 0 }; 
    size_t size = 0; 
    while (size < nelem(address) && fgets(address + size, sizeof *address, stdin)) 
    { 
     address[size][strcspn(address[size], "\n")] = '\0'; 
     size++; 
    } 
} 

Обратите внимание, что 10 и 351 появляются только один раз здесь ... Не стесняйтесь приспосабливать их по своему усмотрению, в пределах разумного. Если вы можете размножить их в мегабайт, вам может потребоваться рассмотреть другую структуру данных в зависимости от того, что вы намерены делать с этим.

Смежные вопросы