getline().Есть ли функция getline(), сделанная вами самостоятельно, которая может заменить функцию в Windows?
Какие ресурсы доступны для ознакомления и чтения?
size_t getline(char **lineptr, size_t *n, FILE *stream)
getline — это ужасно спроектированная и печально известная дырявая функция, поэтому не должно быть причин, по которым вы хотите использовать ее где угодно, если вы можете избежать ее. Просто используйте fgets. Или, что еще лучше, не проектируйте консольные программы ввода-вывода, как будто мы все еще живем в 1990-х годах.
@Lundin: Ты не можешь быть серьезным!
@BlabbotheVerbose Почему бы и нет? Люди, разрабатывающие консольные программы ввода-вывода, чаще всего ни в чем не серьезны. Для программ системного уровня вы должны использовать argv/argc или, возможно, конвейер или IPC.





Соответствующим стандартом является IEEE Std 1003.1, также называемый POSIX.1 , в частности, его системные интерфейсы, со списком затрагиваемых функций здесь.
Я рекомендую справочные страницы Linux онлайн. Пусть вас не смущает его название, потому что в функциях C (описанных в разделах 2, 3) есть раздел «Соответствие», в котором указывается, какие стандарты стандартизируют эту функцию. Если это C89, C99 и т. д., то он включен в стандарт C; если POSIX.1, то в POSIX; если SuS, то в Единой спецификации Unix, которая предшествовала POSIX; если 4.3BSD, то в старой версии BSD 4.3; если SVr4, то в Unix System V выпуск 4 и так далее.
Windows реализует свои собственные расширения для C и избегает поддержки каких-либо POSIX или SuS, но перенесла некоторые детали из 4.3BSD. Используйте документацию Microsoft, чтобы узнать.
В Linux библиотеки C предоставляют эти функции, если определенные макросы препроцессора определены до того, как будут выполнены какие-либо операторы #include. Они описаны в man 7 feature_test_macros. Обычно я использую #define _POSIX_C_SOURCE 200809L для POSIX и иногда #define _GNU_SOURCE для расширений GNU C.
getline() — отличный интерфейс, а не «дырявый», за исключением, возможно, тех случаев, когда его используют программисты, привыкшие к глупостям Microsoft/Windows, например, невозможность вывода расширенных символов на консоль без расширений только для Microsoft (потому что они просто не не хочу помещать эту реализацию в fwide(), по-видимому).
Наиболее распространенный шаблон использования — инициализация нераспределенного буфера и подходящей переменной длины строки:
char *line_buf = NULL;
size_t line_max = 0;
ssize_t line_len;
Затем, когда вы читаете строку, библиотека C может перераспределить буфер до любого размера, необходимого для размещения строки. Например, цикл построчного чтения вашего файла может выглядеть так:
while (1) {
len = getline(&line_buf, &line_max, stdin);
if (len < 0)
break;
// line_buf has len characters of data in it, and line_buf[len] == '\0'.
// If the input contained embedded '\0' bytes in it, then strlen(line_buf) < len.
// Normally, strlen(line_buf) == len.
}
free(line_buf);
line_buf = NULL;
line_max = 0;
if (!feof(stdin) || ferror(stdin)) {
// Not all of input was processed, or there was an error.
} else {
// All input processed without I/O errors.
}
Обратите внимание, что free(NULL) безопасен и ничего не делает. Это означает, что мы можем безопасно использовать free(line_buf); line_buf = NULL; line_max = 0; после цикла — фактически, в любой момент, когда захотим! –– для сброса текущего буфера строк. Если он нужен, следующий вызов getline() или getdelim() с теми же переменными выделит новый.
Вышеприведенный шаблон никогда не приводит к утечке памяти и правильно обнаруживает все ошибки во время обработки файла, от ошибок ввода-вывода до нехватки оперативной памяти (или разрешенной для текущего процесса), хотя он не может различать их: только то, что произошла ошибка. У него также не будет ложных ошибок, если вы не прервете цикл в своем собственном добавленном коде обработки.
Таким образом, любые заявления о том, что getline() является «дырявым», являются пропагандой против POSIX и в пользу Microsoft. По какой-то причине Microsoft категорически отказывается реализовывать их в своей собственной библиотеке C, хотя легко могла бы это сделать.
Если вы хотите скопировать части строки, я рекомендую использовать strdup() или strndup(), также функции POSIX.1-2008. Они возвращают динамически выделенную копию строки, последняя копирует только до указанного количества символов (если строка не заканчивается до этого); во всех случаях, если функции возвращают ненулевой указатель, динамически выделенная строка завершается нулем '\0' и должна быть освобождена с помощью free() точно так же, как буфер getline() выше, когда он больше не нужен.
Если вам также нужно запускать код в Microsoft, хорошим вариантом является реализация собственного getline() на архитектурах и ОС, которые его не предоставляют. (Вы можете использовать вики Предопределенные макросы компилятора, чтобы узнать, как можно обнаружить код, компилируемый на определенной архитектуре, ОС или компиляторе.)
Пример реализации getline() можно написать поверх fgets(), увеличивая буфер и читая больше (добавляя к существующему буферу), пока буфер не закончится новой строкой. Однако на самом деле он не может обрабатывать встроенные в данные байты '\0'; чтобы сделать это и правильно реализовать getdelim(), вам нужно прочитать данные посимвольно, используя, например. fgetc().
Отвечает ли это на ваш вопрос? Где/как взять функцию "getline", если она отсутствует в stdio.h?