一.char *
fgets(char *s, int n, FILE *stream);
1.fgets函数返回并不一定是读到换行符,因为从stream读到的长度大于n时,数据会被截断只保留n-1个字符加一个'\0'终止符。
错误代码:
-
char buf[BUFSIZ + 1];
-
if (fgets(buf, sizeof(buf), fp)) {
-
if (*buf) { /* see FIO37-C */
-
buf[strlen(buf) - 1] = '\0';
-
}
-
}
-
else {
-
/* Handle error condition */
-
}
正确代码:
-
char buf[BUFSIZ + 1];
-
char *p;
-
if (fgets(buf, sizeof(buf), fp)) {
-
p = strchr(buf, '\n');
-
if (p) {
-
*p = '\0';
-
}
-
}
-
else {
-
/* handle error condition */
-
}
二.调用fflush函数确保数据从读写缓冲区输出
错误代码:
-
/* For brevity, checking for errors on functions was omitted */
-
char digital_signature[SIGNATURE_SIZE];
-
/* ... */
-
FILE *file = fopen("signature_db", "a");
-
/* ... */
-
fwrite(digital_signature, sizeof(char), SIGNATURE_SIZE, file);
-
/* ... */
-
fclose(file)
fwrite调用后,不能保证digital_signature的数据是完整,需要调用fflush来确保缓冲区的数据已经读出并写入到digital_signature中。
正确代码:
-
/* For brevity, checking for errors on functions was omitted */
-
char digital_signature[SIGNATURE_SIZE];
-
/* ... */
-
FILE *file = fopen("signature_db", "a");
-
/* ... */
-
fwrite(digital_signature, sizeof(char), SIGNATURE_SIZE, file);
-
/* Write data buffered in user-space */
-
fflush(file);
-
/* ... */
-
fclose(file)
注意:fflush函数调用会消耗些时间来完成操作。
三.小心使用rename函数
函数原型:
-
int rename(char const *old, char const *new)
若new指向的文件已经存在,其行为依赖于实现。
错误代码:
-
/* program code */
-
char const *old = "oldfile.ext";
-
char const *new = "newfile.ext";
-
if (rename(old, new) != 0) {
-
/* Handle rename failure */
-
}
-
/* program code */
若newfile.ext确定存在,则结果是未定义。
四.setvbuf代替setbuf
原型:
-
void setbuf(FILE * restrict stream, char * restrict buf);
-
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的值,直接读写文件,不再经过文件缓冲区缓冲
错误代码:
-
FILE* file;
-
char *buf = NULL;
-
/* Setup file */
-
setbuf(file, buf);
-
/* ... */
存在的问题就是,无法知道setbuf函数是否成功。
正确代码:
-
FILE* file;
-
char *buf = NULL;
-
/* Setup file */
-
if (setvbuf(file, buf, buf ? _IOFBF : _IONBF, BUFSIZ) != 0) {
-
/* Handle error */
-
}
-
/* ... */
阅读(807) | 评论(0) | 转发(0) |