我用getline函数来读取一行STDIN.
原型getline是:
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
Run Code Online (Sandbox Code Playgroud)
我使用它作为测试程序,来自http://www.crasseux.com/books/ctutorial/getline.html#getline
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int atgc, char *argv[])
{
int bytes_read = 1;
int nbytes = 10;
char *my_string;
my_string = (char *)malloc(nbytes+1);
puts("Please enter a line of text");
bytes_read = getline(&my_string, &nbytes, stdin);
if (bytes_read == -1)
{
puts ("ERROR!");
}
else
{
puts ("You typed:");
puts (my_string);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这很好用.
我的怀疑是?
为什么使用char **lineptr而不是char *lineptr作为函数中的参数getline?
使用以下代码时为什么会出错:
char **my_string;
bytes_read = getline(my_string, &nbytes, stdin);
Run Code Online (Sandbox Code Playgroud)我很困惑*和&.
以下是警告的一部分:
testGetline.c: In function ‘main’:
testGetline.c:34: warning: pointer targets in passing argument 2 of
‘getline’ differ in signedness
/usr/include/stdio.h:671:
note: expected ‘size_t * __restrict__’ but argument is of type ‘int *’
testGetline.c:40: warning: passing argument 1 of ‘putchar’ makes integer
from pointer without a cast
/usr/include/stdio.h:582: note: expected ‘int’ but argument is of
type ‘char *’
Run Code Online (Sandbox Code Playgroud)
我使用GCC版本4.4.5(Ubuntu/Linaro 4.4.4-14ubuntu5).
Thi*_*Not 27
为什么要使用
char **lineptr而不是char *lineptr作为函数的参数getline?
想象一下原型getline看起来像这样:
ssize_t
getline(char *line, size_t n, FILE *stream);
Run Code Online (Sandbox Code Playgroud)
你这么称呼它:
char *buffer = NULL;
size_t len = 0;
ssize_t read = getline(buffer, len, stdin);
Run Code Online (Sandbox Code Playgroud)
在调用之前getline,buffer为null:
+------+
|buffer+-------> NULL
+------+
Run Code Online (Sandbox Code Playgroud)
当getline调用时,line获取一个buffer因为函数参数的副本通过C中的值传递.在内部getline,我们不再有权访问buffer:
+------+
|buffer+-------> NULL
+------+ ^
|
+------+ |
| line +----------+
+------+
Run Code Online (Sandbox Code Playgroud)
getline分配一些内存malloc并指向line块的开头:
+------+
|buffer+-------> NULL
+------+
+------+ +---+---+---+---+---+
| line +------->+ | | | | |
+------+ +---+---+---+---+---+
Run Code Online (Sandbox Code Playgroud)
之后getline的回报,我们不再有机会获得line:
+------+
|buffer+-------> NULL
+------+
Run Code Online (Sandbox Code Playgroud)
我们回到了我们开始的地方.我们无法重新指向buffer新分配的内存,getline因为我们只有一个副本buffer.
原型getline实际上是:
ssize_t
getline(char **lineptr, size_t *n, FILE *stream);
Run Code Online (Sandbox Code Playgroud)
你这样称呼它:
char *buffer = NULL;
size_t len = 0;
ssize_t read = getline(&buffer, &len, stdin);
Run Code Online (Sandbox Code Playgroud)
&foo返回指针foo,所以我们有:
+-------+ +------+
|&buffer+------->+buffer+-------> NULL
+-------+ +---+--+
Run Code Online (Sandbox Code Playgroud)
当getline被调用时,lineptr得到的副本&buffer,因为C是调用-值.lineptr指向同一个地方&buffer:
+-------+ +------+
|&buffer+------->+buffer+-------> NULL
+-------+ +---+--+
^
+-------+ |
|lineptr+------------+
+-------+
Run Code Online (Sandbox Code Playgroud)
getline分配一些内存malloc并指向块开头的指针lineptr(即lineptr指向的东西):
+-------+ +------+ +---+---+---+---+---+
|&buffer+------->+buffer+------->+ | | | | |
+-------+ +---+--+ +---+---+---+---+---+
^
+-------+ |
|lineptr+------------+
+-------+
Run Code Online (Sandbox Code Playgroud)
之后getline的回报,我们不再有机会获得lineptr,但我们仍然可以通过访问新分配的内存buffer:
+-------+ +------+ +---+---+---+---+---+
|&buffer+------->+buffer+------->+ | | | | |
+-------+ +---+--+ +---+---+---+---+---+
Run Code Online (Sandbox Code Playgroud)
Joh*_*ter 12
因为getline()如果传入指向空指针的指针,将为您分配内存.
从手册页:
getline()从流中读取整行,将包含文本的缓冲区的地址存储到*lineptr中.缓冲区以空值终止,并包含换行符(如果找到).
如果*lineptr为NULL,则getline()将分配用于存储该行的缓冲区,该缓冲区应由用户程序释放.(在这种情况下,忽略*n中的值.)
您需要传入一个char**(即指向char的指针),以便该函数能够更新char*它指向的值.
你可以使用:
char *my_string = NULL; // getline will alloc
puts("Please enter a line of text");
bytes_read = getline(&my_string, &nbytes, stdin);
Run Code Online (Sandbox Code Playgroud)
不要忘记,如果你这样做,你负责free()分配的内存getline().
对于你的第一个问题,答案是正确的.将来查看联机帮助页,它提供了您需要的信息.
您的第二行不起作用,因为指针未初始化.如果你想这样做,你需要写:
char **my_string = malloc(sizeof(char**))
Run Code Online (Sandbox Code Playgroud)
本质上,当您创建变量时,*表示指针,当您引用变量时,它意味着取消引用指针(获取指针指向的内容).&表示"指向此的指针".
| 归档时间: |
|
| 查看次数: |
55156 次 |
| 最近记录: |