关于输出打印的,文件流一些函数记录 (fopen、fputs、...)

fopen(打开文件)

相关函数 open, fclose
  表头文件 #include< stdio.h>
  定义函数 FILE * fopen(const char * path,const char * mode);
  函数说明 参数path字符串包含欲打开的文件路径及文件名,参数mode字符串则代表着流形态。
  mode有下列几种形态字符串:
  r 打开只读文件,该文件必须存在。
  r+ 打开可读写的文件,该文件必须存在。
  rb+ 读写打开一个二进制文件,只允许读写数据。
  rt+ 读写打开一个文本文件,允许读和写。
  w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
  w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
  a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
  a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的EOF符不保留)
  wb 只写打开或新建一个二进制文件;只允许写数据。
  wb+ 读写打开或建立一个二进制文件,允许读和写。
  wt+ 读写打开或着建立一个文本文件;允许读写。
  at+ 读写打开一个文本文件,允许读或在文本末追加数据。
  ab+ 读写打开一个二进制文件,允许读或在文件末追加数据。
  上述的形态字符串都可以再加一个b字符,如rb、w+b或ab+等组合,加入b 字符用来告诉函数库打开的文件为二进制文件,而非纯文字文件。不过在POSIX系统,包含Linux都会忽略该字符。由fopen()所建立的新文件会具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)权限,此文件权限也会参考umask 值。
  返回值
  文件顺利打开后,指向该流的文件指针就会被返回。若果文件打开失败则返回NULL,并把错误代码存在errno 中。



  使用打印信息的接口时,经常见到__VA_ARGS__和##__VA_ARGS__这两个字符串,花时间学习下这部分的知识,发现还有#和##这两个比较有意思的字符串,记下他们的用法:
  #: 用来把参数转换成字符串;

#include <iostream>
 
#define LOG(x) do { printf("%s=%d\n",#x,x); }while(0)
 
int main()
{
    int score = 96;
    LOG(score);
    LOG(6);
    
    getchar();
    return 0;
}



##:用于将带参数的宏定义中将两个子串(token)联接起来,从而形成一个新的子串;但它不可以是第一个或者最后一个子串。所谓的子串(token)就是指编译器能够识别的最小语法单元;

#include <iostream>
 
#define LOG(x) log##x()
 
void logA(){
    printf("log func A \n");
}
 
void logB(){
    printf("log func B\n");
}
 
int main()
{
    LOG(A);
 
    getchar();
    return 0;
}




__VA_ARGS__:用于在宏替换部分中,表示可变参数列表;

#include <iostream>
 
#define LOG(...)  printf(__VA_ARGS__);
 
int main()
{
    LOG("score is %d\n",96);
    getchar();
    return 0;
}





##__VA_ARGS__ :和 __VA_ARGS_ 作用类似,## __VA_ARGS__ 宏前面加上 ## 的作用在于,当可变参数的个数为0时,这里的##起到把前面多余的","去掉的作用,否则会编译出错

#include <stdio.h>
#define LOG(...) printf("123+%s=%d\n", __VA_ARGS__)
//#define LOG2(...) printf("123+s=d\n", __VA_ARGS__) //该宏定义GCC下报错,MSVC下未报错
#define LOG2(...) printf("123+s=d\n", ##__VA_ARGS__) //该宏定义GCC、MSVC下均未报错
 
int main()
{
	LOG("3", 123);
	LOG2();
 
	return 0;
}




fflush()函数:更新缓存区
头文件:#include<stdio.h>
函数定义:int fflush(FILE *stream);
函数说明:调用fflush()会将缓冲区中的内容写到stream所指的文件中去.若stream为NULL,则会将所有打开的文件进行数据更新



extern int snprintf (char *__restrict __s, size_t __maxlen, const char *__restrict __format, ...)

(1) 如果格式化后的字符串长度 < size,则将此字符串全部复制到str中,并给其后添加一个字符串结束符(‘\0’);

(2) 如果格式化后的字符串长度 >= size,则只将其中的(size-1)个字符复制到str中,并给其后添加一个字符串结束符(‘\0’),返回值为欲写入的字符串长度。

snprintf的返回值是欲写入的字符串长度,而不是实际写入的字符串度。如:

char buf[8];
int n = snprintf(buf, 5, "abcdefghijk");
printf("n %d    buf %s\n", ret, buf);
 
运行结果为:
n 10     buf abcd

注意这个结果,只输出了abcd,长度为4,不是期待的5,没有输出 e ,说明snprintf函数最后自动加上去的’\0’,是算在size内部的,是格式

化字符串的总长度(不包括’\0’),这里使用sizeof(buf)时需要注意+1,这一点与malloc申请空间类似。

总结:

1.snprintf 会自动在格式化后的字符串尾添加\0,结尾符是包含在size长度内部的。

2.snprintf 会在结尾加上\0,不管buf空间够不够用,所以不必担心缓冲区溢出。

3.snprintf 的返回值n,当调用失败时,n为负数,当调用成功时,n为格式化的字符串的总长度(不包括\0),当然这个字符串有可能被截

断,因为buf的长度不够放下整个字符串。



#include <stdio.h>

int vsnprintf(char* str, size_t size, const char* format, va_list ap);

参数说明

char *str [out],把生成的格式化的字符串存放在这里.

size_t size [in], str可接受的最大字符数 [1] (非字节数,UNICODE一个字符两个字节),防止产生数组越界.

const char *format [in], 指定输出格式的字符串,它决定了你需要提供的可变参数的类型、个数和顺序。

va_list ap [in], va_list变量. va:variable-argument:可变参数

函数功能:将可变参数格式化输出到一个字符数组。

用法类似于vsprintf,不过加了size的限制,防止了内存溢出(size为str所指的存储空间的大小)。

返回值:执行成功,返回最终生成字符串的长度,若生成字符串的长度大于size,则将字符串的前size个字符复制到str,同时将原串

的长度返回(不包含终止符);执行失败,返回负值,并置errno. [2]

备注:

linux环境下是:vsnprintf
VC6环境下是:_vsnprintf

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值