Chinaunix首页 | 论坛 | 博客
  • 博客访问: 329524
  • 博文数量: 57
  • 博客积分: 146
  • 博客等级: 入伍新兵
  • 技术积分: 769
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-29 14:57
文章分类
文章存档

2014年(39)

2013年(13)

2012年(5)

我的朋友

分类: C/C++

2014-07-17 15:29:24

一.char *fgets(char *s, int n, FILE *stream);
1.fgets函数返回并不一定是读到换行符,因为从stream读到的长度大于n时,数据会被截断只保留n-1个字符加一个'\0'终止符。

错误代码:

点击(此处)折叠或打开

  1. char buf[BUFSIZ + 1];
  2. if (fgets(buf, sizeof(buf), fp)) {
  3. if (*buf) { /* see FIO37-C */
  4. buf[strlen(buf) - 1] = '\0';
  5. }
  6. }
  7. else {
  8. /* Handle error condition */
  9. }

正确代码:

点击(此处)折叠或打开

  1. char buf[BUFSIZ + 1];
  2. char *p;
  3. if (fgets(buf, sizeof(buf), fp)) {
  4. p = strchr(buf, '\n');
  5. if (p) {
  6. *p = '\0';
  7. }
  8. }
  9. else {
  10. /* handle error condition */
  11. }


二.调用fflush函数确保数据从读写缓冲区输出

错误代码:

点击(此处)折叠或打开

  1. /* For brevity, checking for errors on functions was omitted */
  2. char digital_signature[SIGNATURE_SIZE];
  3. /* ... */
  4. FILE *file = fopen("signature_db", "a");
  5. /* ... */
  6. fwrite(digital_signature, sizeof(char), SIGNATURE_SIZE, file);
  7. /* ... */
  8. fclose(file)
fwrite调用后,不能保证digital_signature的数据是完整,需要调用fflush来确保缓冲区的数据已经读出并写入到digital_signature中。


正确代码:

点击(此处)折叠或打开

  1. /* For brevity, checking for errors on functions was omitted */
  2. char digital_signature[SIGNATURE_SIZE];
  3. /* ... */
  4. FILE *file = fopen("signature_db", "a");
  5. /* ... */
  6. fwrite(digital_signature, sizeof(char), SIGNATURE_SIZE, file);
  7. /* Write data buffered in user-space */
  8. fflush(file);
  9. /* ... */
  10. fclose(file)
注意:fflush函数调用会消耗些时间来完成操作。

三.小心使用rename函数
函数原型:

点击(此处)折叠或打开

  1. int rename(char const *old, char const *new)
若new指向的文件已经存在,其行为依赖于实现。

错误代码:

点击(此处)折叠或打开

  1. /* program code */
  2. char const *old = "oldfile.ext";
  3. char const *new = "newfile.ext";
  4. if (rename(old, new) != 0) {
  5. /* Handle rename failure */
  6. }
  7. /* program code */
若newfile.ext确定存在,则结果是未定义。

四.setvbuf代替setbuf
原型:

点击(此处)折叠或打开

  1. void setbuf(FILE * restrict stream, char * restrict buf);
  2. int setvbuf(FILE * restrict stream, char * restrict buf, int mode, size_t size)
setbuf函数具有打开和关闭缓冲机制。为了带缓冲进行I/O,参数buf必须指向一个长度为BUFSIZ(定义在stdio.h头文件中)的缓冲区。通常在此之后该流就是全缓冲的,但是如果该流与一个终端设备相关,那么某些系统也可以将其设置为行缓冲。为了关闭缓冲,可以将buf参数设置为NULL。

setvbuf函数,则由malloc函数来分配缓冲区。参数size指明了缓冲区的长度(必须大于0),而参数type则表示了缓冲的类型,其值可以取如下值:
 _IOFBF 文件全部缓冲,即缓冲区装满后,才能对文件读写
 _IOLBF 文件行缓冲,即缓冲区接收到一个换行符时,才能对文件读写
 _IONBF 文件不缓冲,此时忽略buf,size的值,直接读写文件,不再经过文件缓冲区缓冲



错误代码:

点击(此处)折叠或打开

  1. FILE* file;
  2. char *buf = NULL;
  3. /* Setup file */
  4. setbuf(file, buf);
  5. /* ... */
存在的问题就是,无法知道setbuf函数是否成功。

正确代码:

点击(此处)折叠或打开

  1. FILE* file;
  2. char *buf = NULL;
  3. /* Setup file */
  4. if (setvbuf(file, buf, buf ? _IOFBF : _IONBF, BUFSIZ) != 0) {
  5. /* Handle error */
  6. }
  7. /* ... */















阅读(807) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~