2013-08-31 3 views
1

Я знаю, что могу инициализировать массив строк таким образом:Инициализация массива строк динамически в C

static const char *BIN_ELEMENTS[5] = { 
    "0000\0",   // 0 
    "0001\0",   // 1 
    "0010\0",   // 2 
    "0011\0",   // 3 
    "0100\0",   // 4 
}; 

Но мне нужно, чтобы добиться этого в динамике. Чтение символов из файла и вставка их в массив. Затем скопируйте этот массив в массив строк (например, выше).

Так скажем, я захватил следующие символы из файла, и вставить их в массив, как эти:

char number[5]; 
char *listOfNumbers[10]; 
number[0]='1'; 
number[1]='2'; 
number[2]='3'; 
number[3]='4'; 
number[4]='\0'; 

Теперь я хотел бы, чтобы скопировать все содержимое числа, в listOfNumers[0] // смысл что я сохранил «1234» в позиции 0 listOfNumers. Оставляем еще 9 позиций для хранения разных номеров.

Так что я хотел бы сделать что-то вроде этого:

listOfNumers[0] = number; //this actually seems to work. 

Но так как его огромный файл чисел, мне нужно повторно использовать номер массива, чтобы извлечь новый номер. Но когда я это делаю, содержимое, ранее сохраненное в listOfNumers [0], перезаписывается, eventho я обновил новую позицию для нового номера. Как я могу с этим справиться?

Вот то, что я до сих пор:

char number[5]; // array for storing number 
int j=0;  // counter 
int c;   // used to read char from file. 
int k=0;  // 2nd counter 
char*listOfNumbers[10]; // array with all the extracted numbers. 
FILE *infile; 

infile = fopen("prueba.txt", "r"); 

if (infile) { 
    while ((c = getc(infile)) != EOF) { 
     if(c != ' ' && c != '\n') 
      number[k] = c; 
      ++k; 
     } // end inner if 
     else { 
      number[k] = '\0'; 
      listOfNumbers[j] = number; 
      printf("Element %d is: %s\n", j, listOfNumbers[j]); // prints correct value 
      ++j; 
      k=0; 
     } // end else 

    } // end while 
    fclose(infile); 
} // end outer if 

printf("\nElement 0 is: %s\n", listOfNumbers[0]); // fails - incorrect value 
printf("Element 1 is: %s\n", listOfNumbers[1]); // fails - incorrect value 
printf("Element 2 is: %s\n", listOfNumbers[2]);  
+3

Познакомьтесь с 'strcpy()'. –

+2

@simonc ** спасибо **. Я снова могу открыть глаза. – WhozCraig

+3

Вы можете заметить, что '' 0000 "' - это строка, заканчивающаяся нулевым байтом, поэтому вам не нужно добавлять явный нулевой байт в строку с '' 0000 \ 0 "'. –

ответ

1

char * listOfNumbers [10]; только резервирует память для 10 указателей на символ. И listOfNumbers [j] = номер сохраняет только адрес номера массива. Он не копирует содержимое номера массива. Поскольку числовые аддиторы никогда не меняются, каждый из 10 элементов «списка» указывает на одно и то же пространство.

Чтобы зарезервировать место, вам необходимо использовать malloc для каждого из 10 элементов списка ListOfNumber. вам нужно использовать strcpy для копирования содержимого номера в текущий списокOfNumber [k].

listOfNumber[k] = malloc(strlen(number)+1); // reserve space of len 
strcpy(listOfNumbers[k],number) // copy string 

Не забудьте освободить каждый элемент listOfNumbers в конце ... Также обратите внимание на то, что ваш файл может содержать более 10 строк ...

+0

Большое спасибо, за то, что нашли время для чтения моего вопроса и правильно его ответили. Вы очень помогли, и я очень ценю это. Пура-вида! –

+0

Вместо этого вы можете использовать 'strdup (number)', чтобы сделать это намного проще и понятнее. –

0

Что вы делаете, что вы берете буфер пяти char с, возьмите его адрес (number затухает до char* в listOfNumers[0] = number;) и хранить его в массив из десяти char* s. Конечно, это не то, что вы хотели сделать, поскольку конечный результат состоит в том, что все записи в listOfNumbers указывают на тот же буфер и исходная память теряется.

У вас есть два пути решения этой проблемы:

  1. Использование strcpy() как предполагает Н2СО3.

  2. Использование динамической памяти. Если вы используете glibc, asprintf и назначающее расширение scanf - ваши друзья (это POSIX 2008).

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

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