标签:操作 失败 and 取字符串 文件 char hello struct 条件
标准IO函数都是封装在一个库中,这个库就是标准C库,标准C库头文件都是#include <stdio.h>,所以标准IO函数的头文件都是#include <stdio.h>,而且标准IO处理方式与系统IO不一样,读取/写入数据时,都有缓冲区。
系统IO对象 -> 硬件设备文件,例如: 访问LCD液晶,触摸屏,红外传感器,温湿度传感器、超声波传感器
标准IO对象 -> 普通文件,例如: 访问1.txt,2.jpg,3.mp3...
#include <stdio.h>
FILE *fopen(const char *path, const char *mode);
path: 需要访问的文件的路径
mode: 操作文件的权限
r Open text file for reading. The stream is positioned at the beginning of the file.
//以只读方式打开文件,文件的定位在文件的开头! O_RDONLY
r+ Open for reading and writing. The stream is positioned at the beginning of the file.
//以读写方式打开文件,文件的定位在文件的开头! O_RDWR
w Truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the file. //以只写方式打开文件,如果文件不存在则创建,存放则清空,文件的定位在文件开头 O_WRONLY|O_CREAT|O_TRUNC
w+ Open for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file.
//以读写方式打开文件,如果文件不存在则创建,存放则清空,文件的定位在文件开头 O_RDWR|O_CREAT|O_TRUNC
a Open for appending (writing at end of file). The file is created if it does not exist. The stream is positioned at the end of the file.
//以只写方式打开文件,以追加方式写入文件,文件不存在则创建,文件的定位文件的末尾。 O_WRONLY|O_APPEND|O_CREAT
a+ Open for reading and appending (writing at end of file). The file is created if it does not exist. The initial file position for reading is at the beginning of the file, but output is always appended to the end of the file. //以读写方式打开文件,以追加方式写入文件,不存在则创建,如果是读操作,则从文件定位在文件开头,如果是写操作,则文件的定位在末尾。
返回值:
成功:文件指针
失败:NULL
fclose - close a stream
#include <stdio.h>
int fclose(FILE *fp);
fp: 需要关闭的文件流指针
返回值:
成功:0
失败:EOF
#ifndef EOF
# define EOF (-1)
#endif
#define STDIN_FILENO 0 -> 标准输入的文件描述符
#define STDOUT_FILENO 1 -> 标准输出的文件描述符
#define STDERR_FILENO 2 -> 标准出错的文件描述符
extern struct _IO_FILE *stdin; -> 标准输入的文件指针
extern struct _IO_FILE *stdout; -> 标准输出的文件指针
extern struct _IO_FILE *stderr; -> 标准出错的文件指针
#define stdin stdin
#define stdout stdout
#define stderr stderr
===========================================================
文件描述符 文件指针
标准输入 STDIN_FILENO stdin
标准输出 STDOUT_FILENO stdout
标准出错 STDERR_FILENO stderr
练习1:测试fopen("w")中会不会创建,并关闭文件。
#include <stdio.h>
int main()
{
FILE *fp = NULL;
fp = fopen("test.txt","w");
if(fp == NULL)
printf("fopen error!\n");
fclose(fp);
return 0;
}
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
ptr:数据缓冲区
size: 每一个块的字节数
nmemb: 读取的块数
stream:文件流指针
返回值:
成功: 已经读取到的块数。
失败: 0
文件: 30 24 28
3 10 -> 3 3 10 -> 2 3 10 -> 2
2 15 -> 2 2 15 -> 1 2 15 -> 1
5 10 -> 3 5 10 -> 2 5 10 -> 2
#include <stdio.h>
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
ptr:数据缓冲区
size: 每一个块的字节数
nmemb: 写入的块数
stream:文件流指针
返回值:
成功: 已经写入的块数。
失败: 0
练习2: 验证读写返回值。
#include <stdio.h>
int main()
{
FILE *fp = NULL;
//char buf[50] = {0};
int n;
char wbuf[20] = "hello";
fp = fopen("test.txt","r+"); //17
if(fp == NULL)
printf("fopen error!\n");
//n = fread(buf,10,2,fp);
//printf("n = %d\n",n);//1
n = fwrite(wbuf,6,3,fp);
printf("n = %d\n",n);
fclose(fp);
return 0;
}
#include <stdio.h>
int fseek(FILE * stream, long offset, int whence);
stream: 需要进行偏移的文件指针
offset: 需要偏移的偏移量
whence: 基准点
SEEK_SET -> 文件开头
SEEK_CUR -> 文件当前位置
SEEK_END -> 文件末尾
返回值:
成功:0
失败:-1
#include <stdio.h>
long ftell(FILE *stream);
stream:需要获取当前位置距离开头的字节数的文件指针
返回值:
成功: 距离开头的偏移量
失败: -1
#include <stdio.h>
void rewind(FILE *stream);
stream: 文件指针
返回值:无!
等价: fseek(stream, 0, SEEK_SET)
练习3: 使用文件IO中标准IO接口实现文件的拷贝
例如: ./xxx 1.txt 2.txt
要求1: 1.txt必须存在,并且不知道里面有多少个字节数
要求2: 2.txt不存在则创建,存在则清空
要求3: 无论1.txt中有多少个字节,拷贝完后,2.txt必须与1.txt一致。
#include <stdio.h>
int main(int argc,char *argv[]) // ./copy 1.txt 2.txt
{
char buf[10] = {0};
int n;
long a,b;
FILE *fp1 = fopen(argv[1],"r");
if(fp1 == NULL)
printf("fp1 error!\n");
FILE *fp2 = fopen(argv[2],"w");
if(fp2 == NULL)
printf("fp2 error!\n");
while(1)
{
a = ftell(fp1);
n = fread(buf,5,2,fp1);
//还没有到达文件末尾
if(n == 2)
{
fwrite(buf,10,1,fp2);
}
//到达文件末尾
if(n < 2)
{
b = ftell(fp1);
fwrite(buf,b-a,1,fp2);
break;
}
}
fclose(fp2);
fclose(fp1);
return 0;
}
printf()默认的输出对象是标准输出,是有缓冲区。这个缓冲区需要某些特定的条件才会输出数据。
printf()是一个行缓冲区函数,当遇到‘\n‘就会将之前的数据全部输出。
int main(int argc,char *argv[])
{
printf("helloworld");
printf("yueqian");
return 0;
}
结果: 会输出helloworldyueqian
结论: 程序退出时,会刷新printf()函数的缓冲区。
int main(int argc,char *argv[])
{
printf("helloworld");
printf("yueqian");
while(1);
return 0;
}
结果: 不输出任何内容
结论: 程序没有结束的时候,缓冲区是不会输出!
int main(int argc,char *argv[])
{
printf("helloworld");
printf("yueqian\n");
while(1);
return 0;
}
结果: 会输出helloworldyueqian
结论: 当遇到\n时,就会将缓冲区中所有内容都会输出。
sleep(1); -> 进程挂起1秒
usleep(500000); -> 进程挂起0.5秒
int main()
{
while(1)
{
printf("helloworld");
usleep(100000);
}
return 0;
}
结果: 等到缓冲区满了,就会将缓冲区的数据全部输出。
结论: printf()缓冲区满了,即使程序不退出,也没有\n,也是会所有的内容都输出来。
主动刷新数据缓冲区 -> fflush() -> man 3 fflush
NAME
fflush - flush a stream -> 刷新文件流指针
#include <stdio.h>
int fflush(FILE *stream);
stream:需要刷新的文件指针。
返回值:
成功:0
失败:-1
int main(int argc,char *argv[])
{
printf("helloworld");
fflush(stdout);
while(1);
return 0;
}
结果: 会输出helloworld
结论: 当执行fflush(stdout);刷新标准输出的缓冲区时,缓冲区中的内容就会全部输出。
int main()
{
printf("pls input a num:");
scanf("%d",&a);
}
结果: 会输出pls input a num:
结论: 当调用IO函数,就会刷新缓冲区
printf() -> 对象 -> 标准输出 -> 有缓冲区
-> 标准出错 -> 无缓冲区
fprintf() -> 修改输出对象
#include <stdio.h>
int fprintf(FILE *stream, const char *format, ...);
stream: 修改后的对象的文件指针
format: 输出的格式
printf("hello"); 等价于 fprintf(stdout,"hello");
int main()
{
while(1)
{
fprintf(stderr,"helloworld");
usleep(100000);
}
return 0;
}
结果: 每隔0.1S输出一个helloworld。
结论: 标准出错没有缓冲区。
getchar() getc() fgetc() putc() fputc() puts() fputs() fgets()
#include <stdio.h>
int getchar(void);
参数:无
返回值:
成功:获取到的字符
失败:-1
#include <stdio.h>
int main()
{
int ret;
ret = getchar();
printf("%c\n",ret);
return 0;
}
getchar() 等价于 getc(stdin);
#include <stdio.h>
int getc(FILE *stream);
stream: 文件指针
返回值:
成功: 获取到的字符
失败: -1
练习4: 使用getc将某个文件的内容一个一个字符地输出来!
#include <stdio.h>
int main()
{
/*
int ret;
ret = getchar();
printf("%c\n",ret);
*/
FILE * fp = fopen("test.txt","r");
while(1)
{
int ret = getc(fp);
if(ret == -1)
{
break;
}
printf("%c\n",ret);
}
fclose(fp);
return 0;
}
#include <stdio.h>
int putc(int c, FILE *stream);
c: 输出的字符
stream: 文件指针
返回值:
成功: 写入的字符
失败: -1
fputs() -> 输出字符串到文件指针上 -> man 3 fputs
int fputs(const char *s, FILE *stream);
int puts(const char *s);
s: 字符串的首地址
stream: 文件指针
返回值:
成功: 没有使用过的整型数据
失败: -1
puts(s) 等价于 printf("%s\n",s);
5. fgets() -> 从键盘中获取字符串 -> 包含\n在内
#include <stdio.h>
char *fgets(char *s, int size, FILE *stream);
s: 缓冲区的地址
size: 字节数大小
stream:文件指针
返回值:
成功:指向s这个区域的地址
失败:NULL
#include <stdio.h>
int main()
{
char buf[50] = {0};
fgets(buf,50,stdin);
printf("buf = %s",buf);
if(strncmp(buf,"hello",5) == 0) 如果使用strcmp(),就不匹配!
{
printf("ok!\n");
}else{
printf("error!\n");
}
return 0;
}
标签:操作 失败 and 取字符串 文件 char hello struct 条件
原文地址:https://www.cnblogs.com/zjlbk/p/11252167.html