C語言快速入門系列(八) C語言快速入門系列(八) C語言位運(yùn)算與文件 本章引言: 在不知不覺中我們的C快速入門系列已經(jīng)慢慢地接近尾聲了,而在這一節(jié)中,我們會(huì)對(duì) C語言中的位運(yùn)算和文件進(jìn)行解析,相信這兩章對(duì)于一些人來說是陌生的,因?yàn)楹芏?/span> 老師都會(huì)跳過這兩個(gè)大知識(shí)點(diǎn),其實(shí)這兩個(gè)也是灰常重要的!比如一個(gè)問題,叫你算 變量a乘以2,怎么寫效率高?直接a *2,很多人都這樣寫,但是如果你會(huì)位運(yùn)算的話,你會(huì)a<<1; 位運(yùn)算的效率可是比a*2高的哦!另一個(gè)問題,不用變量左中間值,直接交換兩個(gè)變量的值? 你怎么做?也是用到位運(yùn)算!文件操作重要性就不用說啦!好了,請(qǐng)讀者跟隨筆者的腳步 對(duì)C語言中的位運(yùn)算與文件讀寫的核心知識(shí)點(diǎn)進(jìn)行剖析吧~ 本節(jié)學(xué)習(xí)路線圖:位運(yùn)算:ps:位運(yùn)算符并不改變變量自身的值,可以在運(yùn)算符后加上等號(hào): a &= b 等同于a = a&b ! 文件:文本文件的使用方式:
ps:對(duì)于二進(jìn)制文件,對(duì)應(yīng)的只要改成在每個(gè)后面加上一個(gè)b就可以了:
如: r --> rb r+ = rb+ 文件詳細(xì)學(xué)習(xí)圖:使用代碼示例:①單個(gè)字符寫入/讀取寫入: fputc() <span style="font-family:Microsoft YaHei;">#include <stdio.h> #include <string.h> int main() { FILE *fp; char str[] = "Write The Data to File!"; int index = 0; fp = fopen("test1.txt","w"); if(fp == NULL) { printf("文件打開失敗!\n"); exit(1); } //因?yàn)槭且粋€(gè)個(gè)字符輸入的,所以要獲得長度 while(index < strlen(str)) fputc(str[index++],fp); fclose(fp); return 0; } </span>
讀取:fgetc() <span style="font-family:Microsoft YaHei;">#include "stdio.h" int main() { FILE *fp; char c; int n = 1; if((fp = fopen("test1.txt","r")) == NULL) { printf("文件打開失敗!\n"); exit(1); } //EOF是文件結(jié)尾的標(biāo)志,此處是判斷是否到文件尾 while((c = fgetc(fp)) != EOF) { printf("%c",c); n++; } printf("\n"); fclose(fp); return 0; } </span>
運(yùn)行截圖: ps:如果不寫完整路徑的話,比如:d:\\c_code\\day 8的話,會(huì)在代碼所在的目錄下生成對(duì)應(yīng)的文本文件! ②讀寫一個(gè)字符串:寫入fputs() <span style="font-family:Microsoft YaHei;">/* fputs(字符串,fp) 作用:向fp所指的文件中,將字符串寫入,'\0'并不寫入! */ #include <stdio.h> int main() { char str[] = "通過fputs方法往文件中寫入信息!"; FILE *fp = fopen("test2.txt","w"); if(fp == NULL) { printf("文件打開失敗!\n"); exit(1); } fputs(str,fp); fclose(fp); return 0; }</span>
讀取:fgets() <span style="font-family:Microsoft YaHei;">/* fgets(字符串?dāng)?shù)組,n,文件指針) 就是:從fp執(zhí)指向的文件中讀取一個(gè)長度為n - 1的字符串, 存儲(chǔ)在一維字符數(shù)組中 ,因?yàn)樽址畷?huì)默認(rèn)添加一個(gè)'\0' */ #include <stdio.h> int main() { FILE *fp; char str[20]; if((fp = fopen("test2.txt","r")) == NULL) { printf("文件打開失敗!\n"); exit(1); } //這里寫3是因?yàn)?漢字是占2個(gè)字節(jié)的 while(fgets(str,3,fp) != NULL) printf("%s",str); printf("\n"); fclose(fp); return 0; }</span>
運(yùn)行截圖: ③格式化讀寫函數(shù)這個(gè)和之前學(xué)的scanf()和printf()使用方法一樣,但是,前者是針對(duì)內(nèi)存中的數(shù)據(jù)的; 而fscanf(0和fprintf()則對(duì)應(yīng)文件讀寫的! ps:要注意哦!fprintf是將控制臺(tái)的內(nèi)容打印到文件中哦!所以是寫入 fscanf()是將文件中的內(nèi)容輸入到控制臺(tái)哦! 所以是讀取 寫入fprint: <span style="font-family:Microsoft YaHei;">#include <stdio.h> int main() { char c[] = "Today is 2014 July "; int day = 22; char a = 't',b = 'h'; FILE *fp; if((fp = fopen("test3.txt","w"))== NULL) { printf("文件打開失敗!\n"); exit(1); } fprintf(fp,"%s%d %c%c",c,day,a,b); fclose(fp); return 0; }</span>
讀取fscanf() <span style="font-family:Microsoft YaHei;">#include <stdio.h> int main() { //這里很容易出問題,所以我并不喜歡用fscanf這個(gè)函數(shù) char c1[5],c2[5],c3[5],c4[5],c5[5],c6[5]; int day,year; FILE *fp; if((fp = fopen("test3.txt","r"))== NULL) { printf("文件打開失敗!\n"); exit(1); } //這個(gè)要按照讀取的文件的格式寫,我弄了N久還是不行 //就直接用6個(gè)字符串了... fscanf(fp,"%s%s%s%s%s%s",&c1,&c2,&c3,&c4,&c5,&c6); printf("%s %s %s %s %s %s\n",c1,c2,c3,c4,c5,c6); fclose(fp); return 0; }</span>
運(yùn)行截圖: 二進(jìn)制文件的讀寫示例代碼:將學(xué)生信息存儲(chǔ)到結(jié)構(gòu)體中,然后通過fwrite()函數(shù)將結(jié)構(gòu)體內(nèi)容寫入文件中; 在通過fread()函數(shù)讀取出來 ①數(shù)據(jù)塊方式寫入:示例代碼: <span style="font-family:Microsoft YaHei;">#include <stdio.h> typedef struct { int id; char name[20]; int age; }STU; int main() { STU stu; FILE *fp; char c; //內(nèi)容是追加的! if((fp = fopen("test4.data","ab"))== NULL) { printf("文件打開失敗!\n"); exit(1); } //錄入多個(gè)學(xué)生的信息: while(1) { printf("請(qǐng)輸入學(xué)號(hào): ");scanf("%d",&stu.id); printf("\n請(qǐng)輸入姓名: ");scanf("%s",&stu.name); printf("\n請(qǐng)輸入年齡: ");scanf("%d",&stu.age); //參數(shù)依次是: 數(shù)據(jù)起始地址,每次寫入的數(shù)據(jù)塊的字節(jié)數(shù),數(shù)據(jù)塊的數(shù)目,文件指針 fwrite(&stu,sizeof(stu),1,fp); printf("\n繼續(xù)輸入?(Y/N)\n"); getchar(); c = getchar(); if(c == 'y' || c == 'Y')continue; else break; } fclose(fp); return 0; }</span> 運(yùn)行截圖:
②數(shù)據(jù)塊方式讀取:示例代碼: <span style="font-family:Microsoft YaHei;">#include <stdio.h> typedef struct { int id; char name[20]; int age; }STU; int main() { STU stu; FILE *fp; if((fp = fopen("test4.data","rb"))== NULL) { printf("文件打開失敗!\n"); exit(1); } //讀取存儲(chǔ)的學(xué)生信息 printf("輸出文件中的內(nèi)容:\n"); printf("學(xué)生學(xué)號(hào) 學(xué)生姓名 學(xué)生年齡\n"); //從fp指向的二進(jìn)制文件讀取數(shù)據(jù),每次讀取大小為size個(gè)字節(jié)的數(shù)據(jù) //執(zhí)行 1 次;最后將這些數(shù)據(jù)保存到結(jié)構(gòu)體變量的地址內(nèi)存中 //返回值正常時(shí)是讀取的數(shù)據(jù)庫個(gè)數(shù)(count)的值,否則返回0(錯(cuò)誤或文件尾) while(fread(&stu,sizeof(stu),1,fp) == 1) { printf("%-15d%-15s%-15d\n",stu.id,stu.name,stu.age); } fclose(fp); return 0; }</span>
②字輸入/輸出函數(shù)getw和putw兩個(gè)函數(shù)并不是ANSI C標(biāo)準(zhǔn)定義的函數(shù),但很多的C語言編譯系統(tǒng)都提供這兩個(gè)函數(shù), 如果沒提供也可以自己寫,這個(gè)用的不多,就不給出代碼示例了,只給出函數(shù)用法: putw(n,fp):以二進(jìn)制的形式將一個(gè)int類型的數(shù)據(jù)寫入到fp所指向的二進(jìn)制文件中! n為寫入的整數(shù),執(zhí)行正常返回寫入的整數(shù),否則返回EOF getw(fp):從fp指向的二進(jìn)制文件中以二進(jìn)制的方式讀取一個(gè)字 執(zhí)行正常返回所讀取的二進(jìn)制整數(shù),否則返回EOF 本章小結(jié):①位運(yùn)算: 1.什么是位運(yùn)算,位運(yùn)算的6個(gè)運(yùn)算符的作用 2.位運(yùn)算的使用,原碼,補(bǔ)碼與反碼的概念 3.位運(yùn)算的相關(guān)應(yīng)用(代替乘法運(yùn)算,不使用中間變量等) ②文件 1.為什么要用文件?文件的分類 2.文件類型指針 FILE *fp; 3.文件打開關(guān)閉: fopen()打開 fclose()關(guān)閉 4.文件的讀寫操作 1)字符讀寫:fgetc 和 fputc 2)字符串讀寫:fgets 和 fputs 3)格式化讀寫:fscanf 和 fprintf 4)數(shù)據(jù)塊讀寫:fwrite 和 fread 5)字讀寫(整數(shù)) getw和putw 5.文件定位: rewind(fp) 移動(dòng)指針到文件頭 fseek()將指針移動(dòng)到某個(gè)地方 ftell(fp) 返回指針的相對(duì)位移量 6.文件狀態(tài)檢查函數(shù):feof(fp)文件是否結(jié)束 ferror(fp)執(zhí)行輸入輸出時(shí)文件是否出錯(cuò),返回0表示沒出錯(cuò) clearerr(fp):重新設(shè)置文件出錯(cuò)標(biāo)志,無返回值 |
|