Kervate, включите предупреждения компилятора (-Wall
для gcc) и прислушайтесь к ним. Они полезны; почему бы не принять всю помощь, которую вы можете получить?
Как указано WhozCraig и n.m. в комментариях к исходному вопросу, getdelim() man page
показывает правильное использование.
Если вы хотите читать записи с разделителями характером NUL, вы могли бы использовать
FILE *input; /* Or, say, stdin */
char *buffer = NULL;
size_t size = 0;
ssize_t length;
while (1) {
length = getdelim(&buffer, &size, '\0', input);
if (length == (ssize_t)-1)
break;
/* buffer has length chars, including the trailing '\0' */
}
free(buffer);
buffer = NULL;
size = 0;
if (ferror(input) || !feof(input)) {
/* Error reading input, or some other reason
* that caused an early break out of the loop. */
}
Если вы хотите прочитать содержимое файла в единый массив символов, то getdelim()
неправильная функция.
Вместо этого используйте realloc()
для динамического выделения и роста буфера, добавляя к нему с помощью fread()
. Чтобы вы начали - это еще не все! - рассмотрим следующий код:
FILE *input; /* Handle to the file to read, assumed already open */
char *buffer = NULL;
size_t size = 0;
size_t used = 0;
size_t more;
while (1) {
/* Grow buffer when less than 500 bytes of space. */
if (used + 500 >= size) {
size_t new_size = used + 30000; /* Allocate 30000 bytes more. */
char *new_buffer;
new_buffer = realloc(buffer, new_size);
if (!new_buffer) {
free(buffer); /* Old buffer still exists; release it. */
buffer = NULL;
size = 0;
used = 0;
fprintf(stderr, "Not enough memory to read file.\n");
exit(EXIT_FAILURE);
}
buffer = new_buffer;
size = new_size;
}
/* Try reading more data, as much as fits in buffer. */
more = fread(buffer + used, 1, size - used, input);
if (more == 0)
break; /* Could be end of file, could be error */
used += more;
}
Обратите внимание, что buffer
в этом последнем фрагменте не является строкой. Не существует завершающего символа NUL, поэтому это всего лишь массив символов. Фактически, если файл содержит двоичные данные, массив может содержать много NUL (\0
, нулевые байты). Предполагая, что ошибки не было, и весь файл был прочитан (вам нужно проверить это, см. Предыдущий пример), buffer
содержит used
chars, читаемый из файла, с достаточным пространством, выделенным для size
. Если used > 0
, то size > used
. Если used == 0
, то size
может быть или не быть равным нулю.
Если вы хотите повернуть buffer
в строку, вам нужно решить, что делать с возможными встроенными байтами \0
. Я рекомендую либо преобразовать, например, пробелов или вкладок или переместить данные, чтобы пропустить их вообще, - и добавьте завершающий строку \0
в конец, чтобы сделать его допустимой строкой.
Вы знаете, что вы передаете NULL (как 0) для второго параметра. [Проверьте документацию] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/getdelim.html), потому что я не верю, что это разрешено. Функция ожидает 'size_t *'; значение * указывает на * может быть '0', но сам указатель не может быть так. И 'buffer' содержит адрес динамического буфера, выделенный из семейства' malloc', он также должен быть 'NULL' на входе. – WhozCraig
Я пробовал, но это все равно дало то же самое.Он игнорирует значение размера, если первый аргумент равен NULL. – Arcana
Он игнорирует значение ** на ** адрес размера; он не игнорирует сам адрес. Он по-прежнему будет использовать адрес для хранения размера вывода. Фактически вы используете нулевой символ (0-октет) в качестве разделителя? действительно? – WhozCraig