目錄
1.標準io;?stdio.h
1.1標準io的概念?
1.2Linux操作系統當中IO都是對文件的操作
1.3標準IO:ANSI?C?設計的一組用文件IO?封裝的操作庫函數
2.文件
2.1作用
2.2linux中文件的類型
3.man??
5.流:???FILE*
5.1流的定義
5.2流的分類
6.c語言文件讀寫操作函數
6.1操作步驟
6.2函數
6.2.1打開
fopen
6.2.2讀寫操作相關
1)fputc
2)fgetc
3)fputs
4)fgets
注意:
5)fwrite(二進制)
6) fread(二進制)
6.2.3關閉
fclose
7.緩沖
7.1行緩沖
7.1.1大小
7.1.2操作位置
7.1.3刷新條件
7.1.4操作指令
7.2全緩沖
7.2.1大小
7.2.2作用
7.2.3刷新條件
7.3無緩沖
7.3.1大小
7.3.2作用
7.3.3不對數據緩存直接刷新
8.標準IO之文件定位
8.1fseek
8.2ftell
8.3rewind
1.標準io;?stdio.h
1.1標準io的概念?
1975?Dennis?r?IO庫,C語言的標準,ANSI?c?
IO??input??output
I:?鍵盤是標準輸入設備?====》默認輸入就是指鍵盤??/dev/input
O:?顯示器是標準輸出設備?==》默認輸出就是指顯示器
1.2Linux操作系統當中IO都是對文件的操作
C一部分,任何支持標準C的系統都可使用標準IO實現文件存儲
標準IO在UNIX上是對文件IO的封裝?
一般都是對普通文件操作是一種有緩存的IO?在文件IO和用戶程序之間,加入緩沖區,可以有效減少系統調用的效率,節省系統IO調度資源
1.3標準IO:ANSI?C?設計的一組用文件IO?封裝的操作庫函數
頭文件:?stdio.h??==》標準輸入輸出頭文件
?????????/usr/include/stdio.h
<>???是系統庫函數,默認路徑在/usr/include/
eg?:?====》stdio.h??===>stdio.c==>libc.so?==>/usr/lib??so?動態庫
""???是用戶自定義函數,默認是當前路徑
eg?:?===>xxx.h??===>xxx.c
2.文件
2.1作用
linux中一切都是文件。文件用來存儲數據(數據,指令);
2.2linux中文件的類型
7種,d ,-,l,p管道,s,c,b?用命令演示??link?pip?socket
hello??oellh,,512?
io的分類
標準io,
stdio.h
Dennis?Ritchie
3.man??
man??==>所有man的幫助
man??xxx?==?man?1?xxx?===>查看當前xxx命令
man?2?xxx??===>查看xxx對應的系統調用函數
man?3?xxx??===》查看xxx對應的標準庫函數
注意:如果沒有命令則直接man?xxx?會顯示其函數\n
? ? ? ? ? ?如果沒有系統調用則顯示系統庫函數幫助
printf?scanf?
sprintf
getchar?putchar?gets?puts\n
getc?putc?fgets?fputs?fread?fwrite?ftell
rewind?fseek
文件io,系統調用,底層軟件
文件內容的分類,?文本文件,二進制文件?????
5.流:???FILE*
struct?FILE
{
}
5.1流的定義
數據從文件當中流入和流出所體現出來的字節流叫做流
5.2流的分類
1)二進制流:?2001?\n
2)二進制數據的流
3)文本流:
4)ASCII碼數據的流?\n?\t?
5)FILE?結構定義的對象?FILE?*?稱之為流對象,也叫文件流指針。
流對象?===》頭?《===數據====》尾
stdin??FILE*???scanf?();
stdout?????????printf();
stderr
6.c語言文件讀寫操作函數
6.1操作步驟
1)打開文件??FILE?
2)io操作,讀寫操作
3)關閉文件??
6.2函數
6.2.1打開
fopen
“r”---只讀 文件必須存在
“w”---創建文件,若文件存在則清空
“r+”---文件存在,進行讀寫
“w+”---創建一個用于讀寫的空文件
“a”---文件不存在則創建,追加 找到文件的末尾
“a+”---找到文件末尾讀寫
#include<stdio.h>int main(int argc,char *argv[])
{FILE*fp=fopen("1.txt","w");if(NULL==fp){fprintf(stderr,"open error\n");return 1;}return 0;
}
6.2.2讀寫操作相關
fgetc/fputc,,,,,,一個字符
1)fputc
int fputc(int C,FILE *stream);
功能:向指定的文件流寫入單個字符數據。
特點:每次只寫入一個字符。
#include<stdio.h>int main(int argc,char *argv[])
{//1 open file//2 read write// close file// 打開,如果文件不存在,創建文件,// 如果存在,清空文件內容 wFILE*fp=fopen("1.txt","w");if(NULL==fp){fprintf(stderr,"open error\n");return 1;}fputc('h',fp);fputc('e',fp);fputc('l',fp);fputc('l',fp);fputc('o',fp);fclose(fp);
}
fgetc(int?c?,FILE*strem);
2)fgetc
int fgetc(FILE *stream);?
功能:?從指定的文件流中逐個字符地讀取數據。
特點:?每次只讀取一個字符,并隨著每次調用向前移動文件指針。返回值類型為 int,以容納 EOF 的負數值。
#include<stdio.h>int main(int argc,char*argv[])
{FILE*fp=fopen("1.txt","r");if(NULL==fp){fprintf(stderr,"open error\n");return 1;}while(1){int c=fgetc(fp);if(EOF==c){break;}printf("%c",c);}return 0;
}
fgets/fputs....,,一次一行
3)fputs
?int fputs(const char *s,FILE *stream);
功能:向指定的文件流寫入字符串數據。
特點:將整個字符串一次性寫入文件。不會在字符串末尾自動添加換行符,如果需要換行,應在字符串中顯式添加。
#include <stdio.h>int main(int argc, char **argv)
{FILE*fp=fopen("1.txt", "w"); //清空 創建if(NULL==fp){printf("fopen error\n");return 1;}//文本文件的寫fputs("hello\n",fp); //常量char buf[]="world";fputs(buf, fp); //變量fclose(fp);// system("pause");return 0;
}
4)fgets
char *fgets(char *s, int size, FILE *stream);?
功能:從指定的文件流中讀取一行字符串,并將其存儲到指定的字符數組中。
特點:會一次性讀取一整行,包括換行符(‘\n’),并將其存儲到目標數組中。可以指定最大讀取的字符數,以防止緩沖區溢出。
#include <stdio.h>int main(int argc, char **argv)
{FILE*fp=fopen("1.txt", "r"); //文件已存在if(NULL==fp){printf("fopen error\n");return 1;} char buf[512]={0};while(1){char *tmp=fgets(buf, sizeof(buf), fp);if(NULL==tmp) //到文件的結尾{break;}printf("%s",buf);}fclose(fp);// system("pause");return 0;
}
注意:
1)fputs和fgets只處理文本文件不處理二進制文件
2)od -c 文件
eg:od -c 1.txt? ?----查看1.txt具體內容
3)od -t x1 1.png | less?
----用十六進制查看1.png具體數值
4)hexdump 1.png -C ?|less??
-----十六進制轉儲顯示并顯示ascii碼
5)vimdiff? -----比較兩個文件差異
eg: vimdiff? ?/ect/passwd? 1.txt? ?比較passwd和1.txt的差異
5)fwrite(二進制)
size_t fwrite(const void *ptr,size_t size, size_t nmemb, FILE *Stream);
自定義大小
#include <stdio.h>
#include <string.h>typedef struct {int id;char name[50];char addr[100];}PER;int main(int argc, char **argv)
{FILE*fp=fopen("1.txt", "w");if(NULL==fp){printf("fopen error\n");return 1;}PER per;bzero(&per, sizeof(per));per.id=10;strcpy(per.name, "zhangsan");strcpy(per.addr, "成都");size_t ret=fwrite(&per, sizeof(per), 1, fp); printf("write num of item:%lu\n",ret);fclose(fp);return 0;// system("pause");return 0;
}
6) fread(二進制)
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
struct?person
{
char?name[10];
int?age;
char?phone[15];
};
person?son[10];?
#include <stdio.h>
#include <string.h>typedef struct {int id;char name[50];char addr[100];}PER;int main(int argc, char **argv)
{FILE*fp=fopen("1.txt", "r");if(NULL==fp){printf("fopen error\n");return 1;}PER per;bzero(&per,sizeof(per));size_t ret=fread(&per, sizeof(per), 1, fp);printf("ret:%lu id:%d name:%s addr:%s\n",ret,per.id,per.name,per.addr);fclose(fp);// system("pause");return 0;
}
注意:
atoi----將字符轉換為數字
6.2.3關閉
fclose
7.緩沖
產生原因:內存和屏幕有快有慢
7.1行緩沖
7.1.1大小
1k -----1024
7.1.2操作位置
terminal,主要用于人機交互stdout
行緩存多是關于終端的一些操作
緩存區滿或者遇到\n刷新
7.1.3刷新條件
1.遇到\n刷新
2.緩存區滿刷新
3.程序結束刷新
4.fflush刷新??fflush(stdout);?
7.1.4操作指令
?FILE*fp?????
標準輸入(鍵盤)stdin?
標注輸出(屏幕)stdout?
標準錯誤輸出(屏幕)stderr?
#include <stdio.h>
// #include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv)
{
// 情況1// printf("hello");// while(1);//情況2 緩存大小是 1024 字節
// int i = 0;
// for (i = 0; i < 1024; i++)
// {
// fputc('a', stdout); // FILE* 標準輸入(鍵盤)stdin 標準輸出(屏幕) stdout
// // 標準錯誤輸出(屏幕) stderr
// }
// sleep(5);
// fputc('a', stdout);
// while (1);//情況3 程序正常結束//printf("hello");//情況4 強制刷新緩沖區printf("hello");fflush(stdout);while(1);return 0;
}
7.2全緩沖
7.2.1大小
4k---4096
7.2.2作用
主要用于文件的讀寫
緩存區滿刷新緩存區?
對普通文件進行標準IO操作,建立的緩存一般為全緩存
7.2.3刷新條件
1.緩存區滿刷新
2.程序正常結束刷新
3.fflush來刷新??fflush(fp);
#include <stdio.h>
// #include <stdlib.h>
#include <unistd.h>
int main(int argc, char** argv)
{// 1// FILE* fp = fopen("1.txt","w");// fputs("hello",fp);// while(1);// 2 4K// FILE* fp = fopen("1.txt", "w");// int i = 0;// for (i = 0; i < 4096; i++)// {// fputc('a', fp);// }// sleep(10);// fputc('a', fp);// while (1);// 3 fflush();FILE* fp = fopen("1.txt", "w");fputs("hello", fp);fflush(fp);while (1);return 0;
}
7.3無緩沖
7.3.1大小
0k? ----0
7.3.2作用
主要用于出錯處理信息的輸出?stderr?
7.3.3不對數據緩存直接刷新
printf(? );==>>stdout?
fprintf(strerr,"fopen?error?%s",filename);
界面交互 出錯處理
使用gdb查看,FILE結構體,或使用寫入數據測試緩沖區。
緩沖區的大小是可以設置
8.標準IO之文件定位
fseek??ftell??rewind
8.1fseek
int fseek(FILE *stream, long offset, int whlence);
功能:將stream流文件中的文件指針從whence位置開始 偏移offset字節的長度。
參數:
stream要移動文件指針的目標文件流對象。
? ? ? ?注意:不支持設備文件,一般用于普通文件。
offsett要在文件內偏移的距離,單位字節。
? ? ? ? ? ? 如果值為整數,則向文件末尾偏移
? ? ? ? ? ? 如果值為負數,則向文件開頭偏移
whence 偏移的起始位置,由系統定義的三個宏開始。
SEEK_SET 文件的開頭位置
SEEK_CUR文件的當前位置
SEEK_END文件的末尾位置
返回值:
成功:返回0
失敗:-1;
如果從文件的指定位置向后偏移過程中已經超過了文件 的當前末尾位置,則會自動以\0'來填充文件內容,從 而形成一種被稱為"空洞文件"的特殊文件。
#include<stdio.h>
#include <stdlib.h>int main(int argc, char **argv)
{FILE*fp=fopen("1.txt","r");if(NULL==fp){fprintf(stderr,"fopen error\n");return 1;}fseek(fp,27,SEEK_SET);char buf[50]={0};fgets(buf,sizeof(buf), fp);fclose(fp);printf("buf:%s\n",buf);// system("pause");return 0;
}
8.2ftell
long ftell(FILE *stream);
功能:
獲得文件大小。
返回文件指針相對于起始位置的偏移量。
參數:
stream要移動文件指針的目標文件流對象。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main(int argc, char **argv)
{FILE*fp=fopen("1.txt", "r");if(NULL==fp){fprintf(stderr, "fopen error\n");}fseek(fp, 0,SEEK_END);long size=ftell(fp);printf("size:%ld\n",size);fclose(fp);// system("pause");return 0;
}
8.3rewind
void rewind(FILE *stream);
功能:
讓文件流指針回到文件開頭(直接復位到開頭)。
rewind(fp);=====fseek(fp,0,SEET_SET);? 二者等價
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main(int argc, char **argv)
{FILE*fp=fopen("1.txt", "r");if(NULL==fp){fprintf(stderr, "fopen error\n");return 1;}fseek(fp, 0, SEEK_END);//文件到達結尾long size=ftell(fp);printf("size:%ld\n",size);char buf[512]={0};rewind(fp);//文件在開頭---pos==0的位置fgets(buf, sizeof(buf), fp);printf("%s\n",buf);fclose(fp);// system("pause");return 0;
}