-
getline
-
功能描述:
前面介绍的scanf、sscanf都设置的静态内存。数据很大时,没法灵活存储。getline使用动态内存技术。getline读取一行,遇到’\0’、‘\n’、EOF结束。遇到‘\n’,会把’\n’读取保存,并结束一行读取。 -
函数定义
#define _GNU_SOURCE
#include <stdio.h>
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
在我的centos 6.3版本中,必须 #define _GNU_SOURCE,getline才能使用。现在最新的很多系统,可能已经不需要了。 -
运行机制
- lineptr:动态分配的存放数据内存地址。
- n:该内存块的大小。单位字节。
- 使用getline时,若lineptr==NULL,则此时的n无意义。getline会自己分配一块内存,并设置n、lineptr的值。
- 若lineptr最初不为空。n字节的内存块也能存放输入的数据,则lineptr与n都不变化。若存放不下,则getline会调用realloc重新分配一块更大的内存,并重新设置n和lineptr的值。
-
返回值
- 读取成功,则返回读取的字节数。会读取间隔字符(包括\n),不会读取\0。(\0被当做一个空行读取,返回0。)如读取"aaa\n",则会返回4。
- 读取失败或者读取到EOF,返回-1。
-
遵循
Both getline() and getdelim() are GNU extensions. They are avail-
able since libc 4.6.27.所以这是个方言,很多系统可能都没这个函数。这个函数很好用,有时得自己实现。 - 注意事项
- getline请求分配了内存,却没有与之对应的释放内存的函数,存在可控的内存泄露。不建议自己使用free(lineptr)释放getline获取的内存。
-
例子:
-
#define _GNU_SOURCE_
#include <stdlib.h>
#include <stdio.h>
int
main()
{
FILE * fp;
size_t n = 0;
ssize_t num;
int count = 0;
char * buf = NULL;//初始化,否则容易出错。
fp = fopen("getline_text","r");
if(fp == NULL)
{
perror("fopen() failed!\n");
exit(EXIT_FAILURE);
}
while((num = getline(&buf,&n,fp))!=-1)
{
fprintf(stdout,"%d : %s",++count,buf);//getline会读取\n并保存在buf中。
fprintf(stdout,"该行长度:%d\n",num);
}
if(fp)
fclose(fp);
exit(EXIT_SUCCESS);
}
-
临时文件
-
关心的两个问题。
- 各个进程间的临时文件如何不冲突。
- 如何确保及时销毁临时文件。
-
tmpnam
char *tmpnam(char *s);
-
功能描述:
tmpnam返回一个指向包含着有效文件名的字符串的指针。系统自己创建一个文件,文件名系统自己给定。有效文件名也就是在同一个目录下,在调用tmpnam时,没有同名的文件,这样程序员就可以认为这个文件名可以作为他的临时文件名。 -
运行机制
- tmpnam首先只创建文件名,并把文件名存储在某个区域,等进程真要访问这个文件时,这个临时文件才会真正被创建。
- 如果s==NULL,则tmpnam会在内部静态区,创造一个文件名。下一次调用tmpnam(NULL)时,就会覆盖上一次创建的文件名。
- 如果s!=NULL,则tmpnam会把临时文件名拷贝到s指向的内存中(要求s指向的内存至少L_tmpnam字节)。
-
-
注意事项
- tmpnam不安全。tmpnam在申请一个临时文件时,并没有实际创建该文件,而是在调用该文件时生成该文件,这两个事件中间的事件差会产生一些安全漏洞(例如:另一个进程创建了一个同名的链接)。而mkstemp在申请一个临时文件时,已生成该文件。
-
tmpfile
-