標準c基礎知識筆記七

honghu79 12年前發布 | 2K 次閱讀 google應用商城

====》IO
 INPUT與OUTPUT
 常規下用scanf/printf即可;從輸入/輸出緩沖區讀
 
 #include <stdio.h>
 
 int main()
 {
  printf("立馬顯示出來");
  fflush(stdout);//刷新顯示
  printf("hello");
  sleep(10);//在windows里面編譯不能通過
  printf("world");
  return 0;
  
 }
 scanf    字符串===》數據
 printf   內存里的數據====》字符序列
 
 什么時候會立馬輸出到屏幕上
 1、有輸入請求的時候,會立馬輸出到屏幕
 2、輸出有換行符的時候,也會馬上輸出到屏幕上
 3、程序結束的時候也會馬上輸出到屏幕上
 4、輸出緩沖區滿的時候
 

 #include  <stdio.h>
 //sscanf,sprintf
 
 int main()
 {
  char buf[100];
  sprintf(buf,"hello,i'm %s ,today is %d-%d-%d\n",
    "wow",2012,05,16);
  //把信息放到buffer數組中
  puts(buf);
  int age;
  char name[20];
  double salary;
  const char * str="21 sxl 2000" ;
  sscanf(str,"%d%s%lf",&age,&name,&salary);
  printf("我是%s,今年%d,月薪%g\n",name,age,salary);
  return 0;
 }
 
 
 1、從鍵盤輸入5各日期,用一個日期數組保存,寫一個通用排序函數,能夠根據傳入的排序規則對日期進行排序,再寫一個函數用來輸出排序
 后的日期。要求寫3個排序規則:一個按年從大到小,一個按月從小到大,一個按整個日期從早到晚。
 2、寫一個過濾函數,根據傳入的過濾規則對一組整數進行過濾,輸出所有符合規則的數據并返回符合規則的數據的個數。
 3、寫一個函數,用來返回一個文件名字符串,格式為imageXXX.jpg,其中XXX是從000開始的三位整數。每次返回一個文件名,每一次跟上一次
 不一樣,到999之后回到000。
 
 
 
 
 內存分配
 
 代碼區
 ——————————————————————————
 靜態全局數據區
 ——————————————————————————
 堆區(自由,一般自己收回)
 ——————————————————————————
 棧區-----一般局部變量;受作用范圍限制
 
 malloc  與 free成對出現
 
 理解指針:
 
 指向數組的指針
 指向函數的指針
 指向結構變量的指針
 指向堆空間的指針
 
 堆空間----用3個函數之一來分配空間malloc/calloc/realloc
 棧空間
 
 指針只能保存地址
 
 memset(地址,數值,字節數)
 
 
 
 sscanf--->sscanf(字符串
    ---->fscanf(文件,===》文件用FILE*指針來表示
 sprintf--->sprintf(字符數組
   --->fprintf(文件,
 
 -------------------------------------------
 操作系統級別一般用一個int fd來表示文件;
 C語言用file*指針來表示文件
 c++用對象來表示文件
 ———————————————————————————————————————————
 
 在C語言中file*指針有3個可用:stdout標準輸出文件,stderr標準錯誤文件,stdin標準輸入文件
 其中stderr是沒有緩沖的;而stdout與stdin是有緩沖的
 而標準輸入和輸出是可以重定向的
 
 fflush(stdout);//刷新標準輸出文件
 
 #include <stdio.h>
 
 int main()
 {
  
  int n;
  double d;
  char str[100];
  fsprintf(stdout,"請輸入姓名、年齡和體重:");
  fscanf(stdin,"%s%d%lf",str,&n,&d);
  fprintf(stdout,"%s:%d歲,%g公斤\n",str,n,d);
  
  return 0;
  
 }
 打開文件用fopen,關閉用fclose
 FILE *fopen(const char *path,const char *mode);
 FILE *Fdopen(int fildes,const char *mode);
 FILE *freopen(const char *path,const char *mode,FILE*stream);
 
 
 FILE*代表一個文件
 
 打開方式
  r從文件開始讀取
  r+讀和寫,從文件開始
  w清0從頭開始寫
  w+如果不存在創建新的,否則將清空,定位在文件開始
  a追加
  a+
 
 
 
 有時間一定去man一下看看
 man   stdio.h
    stdlib.h
    string.h
    time.h
    math.h
   
 
 
 如何實現FILE*呢?
 FOPEN
 
 
 
 類型 * 地址

 
 vi fio.c
 #include <stdio.h>
 
 int main()
 {
 
  FILE* fi=fopen("in","r");//會返回一個FILE*,代表的是一個文件
  //檢查打開文件是否成功?
  if(fi==NULL)
  {
   printf("打開文件in失敗\n");
   return 1;
  }
  char name[20];
  int age;
  double weight;
  
  fscanf(fi,"%s",name);
  fscanf(fi,"%d%lf",&age,&weight);
  fclose(fi);
  printf("姓名:%s,年齡:%d,體重:%g\n",name,age,weight);
  FILE* fo=fopen("out","w");
  if(fo=NULL){
   printf("打開文件out失敗\n");
   return 2;
  }
  fprintf(fo,"向文件寫內容\n");
  fprintf(fo,"姓名:%s,年齡:%d,體重:%g\n",name,age,weight);
  fclose(fo);
  return 0;
 }
 
 //一定要記得關閉,因為寫的文件可能在緩沖區中并沒有寫到文件里面,否則有可能丟失
 
 
 格式串,在輸出的時候還有些格式控制:
 1、整數:%與%之間可以指定寬度,用什么來填充;
 2、%%之間:如果是小數還可以指定寬度.小數位數f
 3、可以指定靠左還是靠右,-表示靠左;默認靠右
 4、%寬度.字符數s    
 以上規則:對于鍵盤,屏幕以及文件都適用
 
 #include <stdio.h>
 
 int main()
 {
  char * s="helloworld"
  printf("%d,%10d,%-10d,%010d,%+d\n",123,123,123,123,123);
  printf("%f,%10f,%-10f,%6.2f\n",1.2,1.2,1.2,1.2);//%f固定6位小數
  printf("%s,%10s,%-10s,%6.3s\n",s,s,s,s);
  int w=10;
  for(w=10;w<15;w++)
  {
   printf("%c,%*c\n",'a',w,'a');
  }
  //在這里寬帶使用*,可變寬度
  printf("input an integer:");
  int x,y;
  scanf("%3d%5d",&x,&y);
  printf("x=%d,y=%d\n",x,y);
  //輸入1234567890,輸出為x=123 y=45678
  //輸入12 3,輸出x=12 y=3
  //輸入12345 輸出x=123 y=45
  scanf("%*d%d",&x);//在scanf中這個*表示拋棄;而在上面printf中表示參數
  printf("x=%d\n",x);
  char str[100],st[100];
  scanf("%[a-z]%[^a-z]",str,st);//讀取在方括號內的字符,比如讀取小寫字符
  //[^]表示不是這個范圍的
  printf("str=%s,st=%s\n",str,st);
  
  return 0;
  
 }
 //其他的輸出格式:

  可以通過man printf來看
 
 從文件讀和從鍵盤讀
 scanf/printf fopen==>FILE*   fclose
 
 puts/gets   fgets/fputs  
 gets會拋棄換行符
 puts在寫時會加上換行符
 自動換行
 fgets從文件讀取一行,不會拋棄換行符,把它作為字符串的一部分
 fputs向文件寫的時候不會加換行符
 
 一般情況下puts/fgets;fputs/gets交叉使用。
 
 #include <stdio.h>
 
 int main()
 {
  char buf[1000];
  printf("請輸入一行文字:\n");
  //gets(buf);
  //scanf("%[^\n]%*c",buf);
  fgets(buf,sizeof(buf),stdin);
  buf[strlen(buf)-1]='\0';//去掉末尾換行符
  puts(buf);
  printf("%s",buf);
  fputs(buf,stdout);//fputs本身并不換行
  return 0;
 }
 
 //配置文件,用戶信息文件/etc/passwd 一般都是一行一行的。
 
 
 讀寫一個字符
 getchar/putchar
 等價scanf("%c"   / printf("%c")
 
 fgetc/fputs
 getc/putc
 
 fgetc一定是一個函數;getc有可能是個函數也可能是個宏
 返回值為int而非char
 不管什么字符都讀取
 
 
 #include <stdio.h>
 int main()
 {
  int i;
  int d;
  for(i=0;i<3;i++)
  {
  // printf("請輸入一個整數:");
  // scanf("%d",&d);
  // scanf("%*[^\n]");scanf("%*c");
  // printf("您輸入的是%d\n",d);
  // getchar();
   d=getchar();
   if(d==EOF){
    printf("讀取終止\n");
    break;
   }
   printf("%c(%d)\n",d,d);
  }
  return 0;
 }
 
 
 #include <stdio.h>
 
 //int fgetc(FILE*)/int fputc(int,FILE*)
 int main(int argc,char* argv[])
 {
  //a.out filename copyfile
  if (argc!=3){
   printf("%s filename copyfile\n",*argv);
   return 0;
  }
  FILE * fi=fopen(argv[1],"r");
  if(fi==NULL){
   printf("無法打開文件%s"\n,argv[1]);
   return 1;
  
  }
  FILE* fo=fopen(argv[2],"w");
  if(fo==NULL){
   printf("無法打開文件%s\n",argv[2]);
   return 2;
  }
  char c;
  while((c=fgetc(fi))!=EOF){//EOF在編譯前會替換成-1
   putchar(c);
   fputc(c,fo);
  }
  fclose(fi);
  fclose(fo);
  return 0;
 }
 
 vi position.c
 #include <stdio.h>
 int main()
 {
  FILE* fp=fopen("file","r+");
  if(fp==NULL)
  {
   printf("無法打開文件file\n");
   return 1;
  }
  int c;
  while((c=fgetc(fp))!=EOF){
   fputc(c,fp);
  
  }
  fclose(fp);
  return 0;
  
 }
 vi file
 abcdefghijklmnopqrstuvwxyz
 
 如何定位文件當前的讀寫呢?fseek函數,設置當前讀寫位置
 feek(哪個文件,位置參數,從哪里算起的偏移量)
 
 可以從當前位置或者某個特定的位置開始的偏移量seek_set,seek_cur,seek_end
 
 ftell取當前位置
 rewind把當前位置設置為文件的最開頭
 
 什么時候使用呢?比如1、音頻或視頻的播放器;2、數據庫
 我們讀取file文件,把第10個和第20個字符交換位置
 
 1、打開文件
 2、讀取出第10個字符
 3、讀取出第20個字符
 4、
 
 #include <stdio.h>
 int main()
 {
  FILE* fp=fopen("file","r+");
  if(fp==NULL){
   printf("無法打開文件file\n");
   return 1;
  }
  fseek(fp,9,SEEK_SET);
  char c10,c20;
  c10=getc(fp);
  fseek(fp,9,SEEK_CUR);//getc讀取完畢后,其位置加1,所以是9
  c20=getc(fp);
  fseek(fp,-11,SEEK_CUR);//用負數,是代表向前
  putc(c20,fp);
  fseek(fp,-8,SEEK_END);//為什么是-8,需要考慮換行符
  putc(c10,fp);
  fclose(fp);
  return 0;
  
 }
 
 
 在內存和文件進行大量的讀寫時,則用fread/fwrite;從文件到內存叫讀;將內存的東西放到文件里面叫寫。
 
 size_t fread(void *ptr,size_t size,size_t nmemb,FILE* stream);
 size_t fwrite(const void *ptr,size_t size,size_t nmemb,FILE* stream);
 對于內存中的數據,主要關注地址而非類型
 
 vi fwrite.c
 #include <stdio.h>
 //fread(內存地址,每條記錄的字節數,記錄的個數,哪個文件)
 //fwrite
 typedef struct person{
  char name[20];
  char gender;
  int age;
  double salary;
 }person;
 int main()
 {
  person a[5]={{"abc",'F',18,3500},{"def",'M',20,4500},{"ghi",'F',20,3000},{"jkl",'F',23,2000},{"mno",'M',22,8000}};
  FILE* fp=fopen("person.dat","wb",);//b在這里的意思是不做任何轉換
  if(fp==NULL){
   printf("打開person.dat文件失敗\n");
   return 1;
  }
  int b[10]={11,22,33,44,55,66,77,88,1010};
  short s=12345;
  fwrite(a,sizeof(person),5,fp);
  fwrite(b,sizeof(int),10,fp);
  fwrite(&s,sizeof(short),1,fp);
  fclose(fp);
  return 0;
 }
 
 以上是將相關信息寫到了person.dat文件中去了。
 
 我們通過fread將信息從person.dat中讀到內存中去
 vi fread.c
 
 #include <stdio.h>
 typedef struct person{
  char name[20];
  char gender;
  int age;
  double salary;
 }person;
 int main()
 {
  person a[5]={};
  int b[10]={};
  short s=0;
  FILE* fp=fopen("person.dat","rb");
  if (fp==NULL){
   printf("打開person.dat文件失敗\n");
   return 1;
  }
  fread(a,sizeof(person),5,fp);
  fread(b,sizeof(int),10,fp);
  fread(&s,sizeof(short),1,fp);
  fclose(fp);
  int i;
  for (i=0;i<5;i++){
   printf("%s:%s,%d,^g\n",a[i].name,a[i].gender='M'?"man":"women",a[i].age,a[i].salary);
  }
  for (i=0;i<10;i++){
   printf("%d ",b[i]);
  }
  printf("\n");
  printf("%hd\n",s);
  
  return 0;
 }
 
 
 
 //ungetc向文件里面退出一個字符;下一次就讀這個字符
 舉例:讀取172.18.9.6或者ftp.xxx.xxx.xxx
 vi ungetc.c
 
 #include <stdio.h>
 int main()
 {
  printf("請輸入一些內容\n");
  char str[1000];
  double data;
  register int c;
  for(;;){
   c=getchar();
   if(c==EOF) break;
   if(isspace(c)) continue;//isblank是不是空白
   ungetc(c,stdin);   
   if(c>='0'&&c<='9'){

    scanf("%lf",&data);
    printf("data=%lf\n",data);
   }
   else{
    scanf("%s",str);
    printf("str=%s\n",str);
   
   }
  }
  return 0;
 }
 
 
 //fgetc(),fgets(),fread(),fwrite()
 //feof(FILE*)//是否超越了文件末尾
 
 

 本文由用戶 honghu79 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!