APUE学习笔记--标准I/O (三)(getline、tmpnam、tmpfile)

  • 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字节)。
      • 返回值
        执行成功,返回指向那个有效文件名的指针。否则返回NULL。
    • 注意事项
      • tmpnam不安全。tmpnam在申请一个临时文件时,并没有实际创建该文件,而是在调用该文件时生成该文件,这两个事件中间的事件差会产生一些安全漏洞(例如:另一个进程创建了一个同名的链接)。而mkstemp在申请一个临时文件时,已生成该文件。
    • tmpfile

      • 功能描述
        tmpfile创建一个匿名二进制文件(w+b)。这个文件会在它关闭时,或者程序终止时,自动被释放。
      • 匿名文件
        • 由于匿名,就建立不了硬链接。则只要这个文件流被关闭,流指针为0时,该内存就可以释放了。
      • 函数定义
        FILE *tmpfile(void);
      • 返回值
        若执行成功,返回一个文件流描述符。若系统无法分配唯一的文件名或者该文件无法打开,则返回-1,且设置对应的errno值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值