目录
- fopen与fopen_s区别
- fgets与fputs函数
- gets与puts函数
fopen与fopen_s区别
在定义FILE * fp 之后,fopen的用法是:fp = fopen(filename,”w”)。而对于fopen_s来说,还得定义另外一个变量errno_t err,然后err = fopen_s(&fp,filename,”w”)。返回值的话,对于fopen来说,打开文件成功的话返回文件指针(赋值给fp),打开失败则返回NULL值;对于fopen_s来说,打开文件成功返回0,失败返回非0。
vs是一个很好的软件编辑器,有时候我们只是希望编写一些c语言的程序,使用vs进行仿真,fopen_s是微软的函数,如果打算移植到linux的环境,或者或者使用gcc等编译器的地方,所以为了移植性,最好使用标准的fopen函数。
为了在vs下屏蔽fopen的报警,需要设置如下:
项目->属性->配置属性->C/C++ -> 预处理器 -> 预处理器定义,增_CRT_SECURE_NO_DEPRECATE
好了,上代码:
#include "stdafx.h"
#include <iostream>
int main()
{
errno_t err;
FILE* fp;
err = fopen_s(&fp,"E:\C++WORKPACE\testChar.txt", "wt");
if (err ==0)
{
printf("The file 'testChar.txt' was not opened");
}
system("pause");
return 0;
}
#include "stdafx.h"
#include <iostream>
int main()
{
FILE* fp;
char fname[50]; //用于存放文件名
printf("输入文件名:");
scanf("%s", fname);
fp = fopen(fname, "wt");
if (fp==NULL)
{
printf("The file 'testChar.txt' was not opened");
}
system("pause");
return 0;
}
常用文件操作方式:
“rt” 只读打开一个文本文件,只允许读数据
“wt” 只写打开或建立一个文本文件,只允许写数据
“at” 追加打开一个文本文件,并在文件末尾写数据
“rb” 只读打开一个二进制文件,只允许读数据
“wb” 只写打开或建立一个二进制文件,只允许写数据
“ab” 追加打开一个二进制文件,并在文件末尾写数据
“rt+” 读写打开一个文本文件,允许读和写
“wt+” 读写打开或建立一个文本文件,允许读写
“at+” 读写打开一个文本文件,允许读,或在文件末追加数 据
“rb+” 读写打开一个二进制文件,允许读和写
“wb+” 读写打开或建立一个二进制文件,允许读和写
“ab+” 读写打开一个二进制文件,允许读,或在文件末追加数据
fgets与fputs函数
fgets:原型是char *fgets(char *s, int n, FILE *stream);
fgets函数用来从文件中读入字符串。fgets函数的调用形式如下:fgets(str,n,fp);此处,fp是文件指针;str是存放在字符串的起始地址;n是一个int类型变量。函数的功能是从fp所指文件中读入n-1个字符放入str为起始地址的空间内;如果在未读满n-1个字符之时,已读到一个换行符或一个EOF(文件结束标志),则结束本次读操作,读入的字符串中最后包含读到的换行符。因此,确切地说,调用fgets函数时,最多只能读入n-1个字符。读入结束后,系统将自动在最后加’\0’,并以str作为函数值返回。
例:如果一个文件的当前位置的文本如下
Love ,I Have
But ………
如果用
fgets(str1,4,file1);
则执行后str1=”Lov”,读取了4-1=3个字符,
而如果用
fgets(str1,23,file1);
则执行str1=”Love ,I Have”,读取了一行(包括行尾的’\n’,并自动加上字符串结束符’\0’)。
fputs:原型是int fputs(const char *s, FILE *stream);
缓冲区s中保存的是以’\0’结尾的字符串,fputs将该字符串写入文件stream,但并不写入结尾的’\0’。与fgets不同的是,fputs并不关心的字符串中的’\n’字符,字符串中可以有’\n’也可以没有’\n’。
#include "stdafx.h"
#include <iostream>
int main()
{
/* 采用fopen_s函数打开文件
errno_t err;
FILE* fp;
err = fopen_s(&fp,"E:\C++WORKPACE\testChar.txt", "rt");
if (err ==0)
{
printf("The file 'testChar.txt' was not opened\n");
}
fclose(fp);
*/
FILE* file1 = fopen("E:\\C++WORKPACE\\testChar1.txt", "r");
FILE* file2 = fopen("E:\\C++WORKPACE\\testChar2.txt", "w");
/*
采用输入命令行方式输入路径
FILE* fp;
char fname[50]; //用于存放文件名
printf("输入文件名:");
scanf("%s", fname);
fp = fopen(fname, "rt");
*/
if (file1 ==NULL)
{
printf("The file 'testChar.txt' was not opened");
}
else
{
char* strBuf = new char[25]; //缓冲区 ;5:读取字符个数
char* str = fgets(strBuf, 25, file1);
// 读取了一行(包括行尾的'\n', 并自动加上字符串结束符'\0')
while (str!= NULL)
{
fputs(strBuf, file2);
str = fgets(strBuf, 15, file1);
}
}
int n = fclose(file1); //关闭
if (n == 0)
{
std::cout << "正常关闭" << std::endl;
}
else {
std::cout << "关闭出错" << std::endl;
}
system("pause");
return 0;
}
gets与puts函数
gets与puts函数
char * gets ( char * str );
gets()若成功则返回s指针,返回NULL则表示有错误发生。
从标准输入stdin读取一个字符串,遇到换行或结束时候终止。不同于fgets(),它没有指定num,所以需要注意字符数组str的大小。读入字符不包括最后的换行符,但自动加上’/0’空字符结尾。
说明: fgets和gets之间没有宏定义的关系,彼此各自有自己的实现。蠕虫病毒的实现就是函数gets的“功劳”。gets函数的任务是从流中读入一个字符串。它的调用者会告诉它把读入的字符串放在什么地方。但是,gets()函数并不检查缓冲区大小 ,如果调用者提供了一个指向堆栈的指针,并且get()函数读入的字符数量超过了超过了缓冲区的空间大小,get()会愉快地将多出来的字符继续写入到堆栈中,这就覆盖了堆栈中原来的内容。
main()
{
char line[512]; //在程序的堆栈上分配512个字符的空间
…
gets(line); //蠕虫病毒的入口,可以将恶意代码通过多出来的数据写入堆栈
}
puts与fputs两者之间无宏定义实现关系。puts(const char *str)近似等效于fputs(cosnt char *str, stdout),不同点是前者还输出一个’/n’。
关于EOF
在C标准库中,像getchar这样的数据读取函数返回一个与符号(宏)EOF相等的值来指明文件结束的情况发生,EOF的真实值与不同的平台有关(但通常是-1,比如在glibc中),并且不等于任何有效的字符代码。
fputc函数返回一个值:如果输出成功则返回值就是输出的字符;如果输出失败,则返回一个EOF。
fgetc函数读字符时遇到文件结束符,函数返回一个文件结束标记EOF。如果想从一个磁盘文件顺序读入字符并在屏幕上显示,可以:
ch = fgetc(fp);
while(ch != EOF){
putchar(ch);
ch = fgetc(fp);
}
注意,EOF不是可输出字符,因此不能在屏幕上显示。由于ASCII码不可能出现-1,因此EOF定义为-1是合适的。 当读入的字符值等于-1(即 EOF)时,表示读入的已不是正常的字符,而是文件结束符。但以上只适用于读取文本文件的情况。现在ANSI C 已经允许用缓冲文件系统处理二进制文件,而读入某一个字节中的二进制数据的值有可能是-1,而这又恰好是EOF的值。这就出现了需要读入有用数据,却处理为“文件结束”。feof(fp) 用来测试fp所指向的文件当前状态是否是“文件结束” 。如果想顺序读入一个二进制文件数据,可以:
int c = fgetc(file1);
while (c!=EOF)
{
//do something;
c= fgetc(file1);
}
if (feof(file1))
{
printf("\n End of file reached.");
}
else
{
printf("\n Something went wrong.");
}
能力有限难免有错,欢迎指教!