Linux C getline, gets, fgets 函式區別
getline, gets, fgets都支援從標準輸入讀取一行字串,那麼它們有什麼區別呢?
getline
getline有2個版本:getline和getdelim。
getline原型
#include <stdio.h>
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream);
getline從stream(流)讀取一整行字串,存放到緩衝區buffer,並將buffer地址儲存到指標lineptr。其中,buffer以空字元('\0')結尾,並且包含換行符。
如果在呼叫getline之前,
如果在呼叫getline之前,buffer不夠大,getline()會用realloc重新分配其大小,同時更新lineptr和*n。
也就是說,getline存放一行字串的buffer可以由呼叫者提供,也可以由函式分配;然而,釋放都是由呼叫者進行。
DESCRIPTION getline() reads an entire line from stream, storing the address of the buffer containing the text into *lineptr. The buffer is null-terminated and includes the newline character, if one was found. If *lineptr is set to NULL and *n is set 0 before the call, then getline() will allocate a buffer for storing the line. This buffer should be freed by the user program even if getline() failed. Alternatively, before calling getline(), *lineptr can contain a pointer to a malloc(3)-allocated buffer *n bytes in size. If the buffer is not large enough to hold the line, getline() resizes it with realloc(3), updating *lineptr and *n as necessary. In either case, on a successful call, *lineptr and *n will be updated to reflect the buffer address and allocated size respectively. getdelim() works like getline(), except that a line delimiter other than newline can be specified as the delimiter argument. As with getline(), a delimiter character is not added if one was not present in the input before end of file was reached. RETURN VALUE On success, getline() and getdelim() return the number of characters read, including the delimiter character, but not including the terminating null byte ('\0'). This value can be used to handle embedded null bytes in the line read. Both functions return -1 on failure to read a line (including end-of-file condition). In the event of an error, errno is set to indicate the cause.
getline使用示例
來自getline page
int main(int argc, char *argv[]) { FILE *stream; char *line = NULL; size_t len = 0; ssize_t nread; printf("hello main\n"); if (argc != 2) { fprintf(stderr, "Usage: %s <file>\n", argv[0]); exit(EXIT_FAILURE); } stream = fopen(argv[1], "r"); if (stream == NULL) { perror("fopen"); exit(EXIT_FAILURE); } while ((nread = getline(&line, &len, stream)) != -1) { printf("Retrieved line of length %zu:\n", nread); fwrite(line, nread, 1, stdout); } free(line); fclose(stream); exit(EXIT_SUCCESS); }
gets
符合C89, C99, POSIX.1-2001.,不過目前已經棄用,推薦使用fgets。
gets(s)
相當於fgets(s, INT_MAX, stdin) + 替換末尾換行符為'\0'
。不過,這樣並不不安全,因為gets不會檢查s是否會溢位。
fgets
fgets原型
#include <stdio.h>
char *fgets(char *s, int size, FILE *stream);
fgets最多從指定stream流讀取 size-1個字元,並且儲存到s指向的buffer中。讀取遇到EOF或換行符停止。每讀取一行,buffer末尾會自動新增'\0'。
fgets() reads in at most one less than size characters from stream and
stores them into the buffer pointed to by s. Reading stops after an
EOF or a newline. If a newline is read, it is stored into the buffer.
A terminating null byte ('\0') is stored after the last character in
the buffer.
也就是說,fgets存放一行字串的buffer必須是由呼叫者提供,fgets不會分配任何儲存字串的空間。