日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言再学习 -- 输入/输出

發布時間:2025/3/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言再学习 -- 输入/输出 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、緩沖區

輸入字符的立即回顯是非緩沖或直接輸入的一個實例,它表示你說鍵入的字符被收集并存儲在一個被成為緩沖區的臨時存儲區域中。按下回車可使你所鍵入的字符塊對程序變成可用。

為什么需要緩沖區?首先,將若干個字符作為一個塊傳輸比逐個發送這些字符耗費的時間少。其次,如果你輸入有誤,就可以使用你的鍵盤更正功能來修改錯誤。當最終按下回車鍵時,你就可以發送正確的輸入。另一個方面,一些交互性的程序需要非緩沖收入。

緩沖分為兩類,完全緩沖I/O和行緩沖I/O。對完全緩沖輸入來說,緩沖區滿時被清空(內容被發送至目的地)。這種類型的緩沖通常出現在文件輸入中。緩沖區的大小取決于系統,但512字節和4096字節是常見的值。對行緩沖I/O來說,遇到一個換行符時將被清空緩沖區。鍵盤輸入時標準的行緩沖,因此按下回車鍵將清空緩沖區。


當輸入函數檢測到已經讀取了緩沖區中的全部字符時,它會請求系統將下一塊緩沖區大小的數據復制到緩沖區,通過這種方式,輸入函數可以讀入文件中的全部內容,直到文件結尾。函數在讀入最后以緩沖區數據中的最后一個字符后,會將文件結尾指示器的值設置為真。于是下一個被調用的輸入函數將返回EOF。

以類似的方式,輸出函數將數據寫入緩沖區,當緩沖區以滿時,就將數據復制到文件中。

緩沖區相關函數:

1、ungetc ( ) 函數

函數原型:
int ungetc(int char, FILE *stream)
參數:
char
-- 這是要被推入的字符。該字符以其對應的 int 值進行傳遞。
stream -- 這是指向 FILE 對象的指針,該 FILE 對象標識了輸入流。
返回值:
如果成功,則返回被推入的字符,否則返回 EOF,且流 stream 保持不變。
函數功能:
把字符 char(一個無符號字符)推入到指定的流 stream 中,以便它是下一個被讀取到的字符。

#include <stdio.h> int main (void) {FILE * fp;int c;char buffer[256];fp = fopen ("abc.txt", "r");if (fp == NULL){perror ("打開文件時發生錯誤");return -1;}while (1){c = getc (fp);if( feof(fp) ) //到文件結尾 feof (fp) 為 1 { break ; } if (c == '!'){ungetc ('+', fp);}else {ungetc (c, fp);}fgets (buffer, 255, fp);fputs (buffer, stdout);}return 0; } 假設我們有一個文本文件 abc.txt,它的內容如下。文件將作為實例中的輸入: this is w3cschool !c standard library !library functions and macros讓我們編譯并運行上面的程序,這將產生以下結果: this is w3cschool +c standard library +library functions and macros +library functions and macros

2、fllush ( )函數

函數原型:
int fflush(FILE *stream)
參數:
stream -- 這是指向 FILE 對象的指針,該 FILE 對象指定了一個緩沖流。
返回值:
如果成功,該函數返回零值。指定的流沒有緩沖區或者只讀打開時也返回0值。如果發生錯誤,則返回 EOF,且設置錯誤標識符(即 feof)。
函數功能:
清除讀寫緩沖區,需要立即把輸出緩沖區的數據進行物理寫入時
fflush()會強迫將緩沖區內的數據寫回參數stream 指定的文件中. 如果參數stream 為NULL,fflush()會將所有打開的文件數據更新.

其他用法編輯
fflush(stdin)刷新標準輸入緩沖區,把輸入緩沖區里的東西丟棄[非標準]
fflush(stdout)刷新標準輸出緩沖區,把輸出緩沖區里的東西打印到標準輸出設備上
printf("。。。。。。。。。。。");后面加fflush(stdout);可提高打印效率


只有滿足如下四個條件中的某一個,輸出緩沖區里的內容才會顯示在屏幕上
1 "\n"換行字符前面的內容會打印在屏幕上
2 當主函數結束后程序打印的內容出現在屏幕上
3 當輸出緩沖區被充滿了的時候里面的內容會被打印在屏幕上
4 可以使用fflush(stdout)語句把輸出緩沖區里的內容強制顯示在屏幕上

#include <stdio.h> int main(void) {int num=0;printf("1"); //一種是加換行fflush(stdout); //把輸出緩沖區里的內容強制顯示在屏幕上while(1); //死循環 //另一種是可以結束return 0; }

3、setvbuf ()函數

函數功能:
定義流 stream 應如何緩沖
函數原型:
int setvbuf(FILE *stream, char *buffer, int mode, size_t size)
參數:
stream -- 這是指向 FILE 對象的指針,該 FILE 對象標識了一個打開的流。
buffer -- 這是分配給用戶的緩沖。如果設置為 NULL,該函數會自動分配一個指定大小的緩沖。
mode -- 這指定了文件緩沖的模式:
模式:
_IOFBF 全緩沖:對于輸出,數據在緩沖填滿時被一次性寫入。對于輸入,緩沖會在請求輸入且緩沖為空時被填充。
_IOLBF 行緩沖:對于輸出,數據在遇到換行符或者在緩沖填滿時被寫入,具體視情況而定。對于輸入,緩沖會在請求輸入且緩沖為空時被填充,直到遇到下一個換行符。
_IONBF 無緩沖:不使用緩沖。每個 I/O 操作都被即時寫入。buffer 和 size 參數被忽略。
size --這是緩沖的大小,以字節為單位。
返回值:
如果成功,則該函數返回 0,否則返回非零值。

注意:This function should be called once the file associated with the stream has already been opened but before any input or output operation has taken place.
意思是這個函數應該在打開流后,立即調用,在任何對該流做輸入輸出前

#include <stdio.h> #include <string.h>int main() {char buff[1024];memset( buff, '\0', sizeof( buff ));fprintf(stdout, "啟用全緩沖\n");setvbuf(stdout, buff, _IOFBF, 1024);fprintf(stdout, "這里是 w3cschool.cc\n");fprintf(stdout, "該輸出將保存到 buff\n");fflush( stdout );fprintf(stdout, "這將在編程時出現\n");fprintf(stdout, "最后休眠五秒鐘\n");sleep(5);return(0); } 讓我們編譯并運行上面的程序,這將產生以下結果。在這里,程序把緩沖輸出保存到 buff,直到首次調用 fflush() 為止,然后開始緩沖輸出,最后休眠 5 秒鐘。它會在程序結束之前,發送剩余的輸出到 STDOUT。 啟用全緩沖 這里是 w3cschool.cc 該輸出將保存到 buff 這將在編程時出現 最后休眠五秒鐘


4、setbuf () 函數

函數功能:

C 庫函數 void setbuf(FILE *stream, char *buffer) 定義流 stream 應如何緩沖。該函數應在與流 stream 相關的文件被打開時,且還未發生任何輸入或輸出操作之前被調用一次。

函數聲明:
void setbuf(FILE *stream, char *buffer)
參數:
stream --
這是指向 FILE 對象的指針,該 FILE 對象標識了一個打開的流。
buffer -- ?這是分配給用戶的緩沖,它的長度至少為 BUFSIZ 字節,BUFSIZ 是一個宏常量,表示數組的長度。
返回值:
該函數不返回任何值。

說明:

setbuf函數具有打開和關閉緩沖機制。為了帶緩沖進行I/O,參數buf必須指向一個長度為BUFSIZE(定義在stdio.h頭文件中)的緩沖區。通常在此之后該流就是全緩沖的,但是如果該流與一個終端設備相關,那么某些系統也可以將其設置為行緩沖。為了關閉緩沖,可以將buf參數設置為NULL。

__BEGIN_NAMESPACE_STD /* If BUF is NULL, make STREAM unbuffered.Else make it use buffer BUF, of size BUFSIZ. */ extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) __THROW; /* Make STREAM use buffering mode MODE.If BUF is not NULL, use N bytes of it for buffering;else allocate an internal buffer N bytes long. */ extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf,int __modes, size_t __n) __THROW; __END_NAMESPACE_STD/* Default buffer size. */ #ifndef BUFSIZ # define BUFSIZ _IO_BUFSIZ #endif

//示例一 #include <stdio.h> char outbuf[BUFSIZ]; int main(void) { setbuf(stdout, outbuf); // 把緩沖區與流相連puts("This is a test of buffered output.\n");puts(outbuf);fflush(stdout); // 刷新puts(outbuf); // 輸出return 0; } 輸出結果: This is a test of buffered output.This is a test of buffered output.This is a test of buffered output.This is a test of buffered output.


程序先把outbuf與輸出流相連,然后輸出一個字符串,這時因為緩沖區已經與流相連,所以outbuf中也保存著這個字符串,緊接著puts函數又輸出一遍,所以現在outbuf中保存著兩個一樣的字符串。刷新輸出流之后,再次puts,則又輸出兩個字符串。為了關閉緩沖,可以將buf參數設置為NULL。

#include <stdio.h> char outbuf[BUFSIZ]; int main(void) { setbuf(stdout, outbuf); // 把緩沖區與流相連setbuf (stdout, NULL); //關閉緩沖puts("This is a test of buffered output.");puts(outbuf);fflush(stdout); // 刷新puts(outbuf); // 輸出return 0; } 輸出結果: This is a test of buffered output. 看一下下面這種寫法對不對:

#include <stdio.h>int main (void) {int c;char buf[BUFSIZ];setbuf(stdout, buf);while((c=getchar())!=EOF)putchar(c);return 0; }
遺憾的是,這個程序是錯誤的,僅僅是因為一個細微的原因。程序中對庫函數 setbuf 的調用,通知了輸入/輸出庫所有字符的標準輸出應該首先緩存在buf中。要找到問題出自何處,我們不妨思考一下 buf 緩沖區最后一次被清空是在什么時候?答案是在main函數結束之后,作為程序交回控制給操作系統之前C運行時庫所必須進行的清理工作的一部分。但是,在此之前buf字符數組已經被釋放!要避免這種類型的錯誤有兩種辦法。
第一種辦法是讓緩沖數組成為靜態數組,既可以直接顯式聲明buf為靜態:

static char buf[BUFSIZ];

也可以把buf聲明完全移到main函數之外。第二種辦法是動態分配緩沖區,在程序中并不主動釋放分配的緩沖區(譯注:由于緩沖區是動態分配的,所以main函數結束時并不會釋放該緩沖區,這樣C運行時庫進行清理工作時就不會發生緩沖區已釋放的情況):
char *malloc();
setbuf(stdout,malloc(BUFSIZ));

如果讀者關心一些編程“小技巧”,也許會注意到這里其實并不需要檢查malloc函數調用是否成功。如果malloc函數調用失敗,將返回一個null指針。setbuf函數的第二個參數取值可以為null,此時標準輸出不需要進行緩沖。這種情況下,程序仍然能夠工作,只不過速度較慢而已。

下面這個例子可以很好的看出上面所講。

#include <stdio.h> //static char outbuf[50]; int main(void) {char outbuf[50];/* 將outbuf與stdout輸出流相連接 */setbuf(stdout,outbuf);/* 向stdout中放入一些字符串 */puts("This is a test of buffered output.");puts("This output will go into outbuf");puts("and won't appear until the buffer");puts("fills up or we flush the stream.\n");/* 以下是outbuf中的內容 */puts(outbuf);/*刷新流*/fflush(stdout); return 0; } 輸出結果: This is a test of buffered output. This output will go into outbuf and won't appear until the buffer fills up or we flush the stream.This is a test of buffered output. This output will go into outbuf and won't appear until the buffer fills up or we flush the stream.段錯誤 (核心已轉儲)


二、鍵盤輸入

參看:C語言再學習 -- 文件

1、鍵盤輸入由一個被稱為sdin的流表示,而屏幕(或電傳打字機,或其他輸出設備)上的輸出由一個稱為stdout的流表示。getchar()、putchar、printf()、scanf()函數都是標準的I/O的成員,這些函數通這兩個流打交道。

2、在printf函數調用語句里用%s做占位符就可以把一個字符串打印在屏幕上可以使用scanf函數從鍵盤得到一個字符串并把它記錄在一個數組里(這個時候要使用%s作為占位符)如果輸入內容有空格則只能得到空格前的部分如果輸入內容超過數組容量則會出現嚴重錯誤fgets函數也可以用來從鍵盤得到字符串并記錄到一個數組里 ?fgets(str,10,stdin)?
這個函數需要三個參數
1 數組名稱
2 數組中存儲區個數
3 用stdin表示鍵盤

如果輸入的字符個數不夠則會把最后輸入的回車當作'\n'字符也放到數組里 ??如果輸入的字符過多則只會截取前面的一部分下次都字符串的時候會從后面沒有處理的內容里讀取應該在每次使用fgets函數獲得字符串以后把可能存在的垃圾數據清理掉清理語句應該放在一個分支里,只有當確保有垃圾數據的時候才需要清理

/*從鍵盤得到字符串演示 */ #include <stdio.h> #include <string.h> int main() {char str[10] = {}; //"01234678'\n'"printf("請輸入一個字符串:");//scanf("%s", str);fgets(str, 10, stdin);//表示從鍵盤上向數組str輸入10個字節if (strlen(str) == 9 && str[8] != '\n')//有效字符個數為9個 && 下標為8的字節不為'\n'{scanf("%*[^\n]");//清空換行符以前的緩沖 scanf("%*c"); //清除換行符 //輸入 "0123456789101112"//得到 "012345678"}printf("%s\n", str);return 0; }

3、判斷文件結尾

C的處理方法是讓getchar()函數在到文件完結為時返回一個特殊值,而不是去管操作系統是如何檢測文件結尾的。賦予該值的名稱為EOF(End Of File)。因此,檢測到文件尾時getchar()的返回值是EOF。scanf()函數在檢測到文件結尾時也返回EOF。通常EOF在stdio.h文件中定義。如下所示:

#define EOF (-1)

將getchar()的返回值與EOF進行比較。如果不相同,則你還沒有到達文件結尾。換句話說,你可以使用如下表達式:

while ((ch = getchar ()) != EOF)

在Unix系統中,你能通過在一行開始鍵入Ctrl+D來從鍵盤模擬文件結束條件;DOS系統則使用Ctrl+Z來達到這個目的。

順便提一句,Linux中按下Ctrl+Z,表示將該進程中斷,在后臺掛起,用?fg?命令可以重新切回到前臺;按下Ctrl+C表示終止該進程。

參看:C語言再學習 -- EOF、feof函數、ferror函數

#include <stdio.h> int main(void) {char ch;while ((ch = getchar ()) != EOF)putchar (ch);return 0; }

三、scanf() 清空緩沖區

在不同速度的設備之間傳遞數據的時候需要使用緩沖區臨時儲存數據
scanf函數工作是會利用有一個輸入緩沖區把用戶在鍵盤上輸入的字符歷史存儲起來,程序實際上從這個輸入緩沖區里獲得數字先進入輸入緩沖區的數據必須優先處理,如果計算機先輸入的內容沒有處理如果用戶輸入的內容和scanf函數要求的格式不一致則他們會一直無法被處理這會導致后面輸入的內容也無法處理,可以使用如下兩條語句把輸入緩沖區里可能存在的錯誤數據丟棄:
scanf("%[^\n]"); ?//把輸入緩沖區里第一個換行字符前的所有內容丟棄
scanf("%*c"); ? ? //把輸入緩沖區里第一個換行字符丟棄

/*輸入緩沖區演示*/ /*如果輸入錯誤scanf之后的內容都無法不能執行*/ #include <stdio.h> int main(void) {int num=0,num1=0;printf("請輸入一個數字:");scanf("%d",&num);scanf("%*[^\n]"); //把輸入緩沖區里第一個換行字符前的所有內容丟棄scanf("%*c"); //把輸入緩沖區里第一個換行字符丟棄printf("num是%d\n",num);printf("請再輸入一個數字:");scanf("%d",&num1);scanf("%*[^\n]");scanf("%*c");printf("num1是%d\n",num1);return 0; }

四、printf() 函數使用輸出緩沖區臨時存儲要打印的內容
只有滿足如下四個條件中的某一個,輸出緩沖區里的內容才會顯示在屏幕上
1 "\n"換行字符前面的內容會打印在屏幕上
2 當主函數結束后程序打印的內容出現在屏幕上
3 當輸出緩沖區被充滿了的時候里面的內容會被打印在屏幕上
4 可以使用fflush(stdout)語句把輸出緩沖區里的內容強制顯示在屏幕上

#include <stdio.h> int main(void) {int num=0;printf("1"); //一種是加換行fflush(stdout); //把輸出緩沖區里的內容強制顯示在屏幕上while(1); //死循環 //另一種是可以結束return 0; } 五、getcahr()和putchar()

getchar ()函數沒有參數,他返回來自輸入設備的下一個字符。例如,下面的語句讀取下一個輸入字符并將它的值賦給變量ch:

ch = getchar();

該語句與下面的語句有同樣的效果: scanf ("%c", &ch);

putchar()函數打印它的參數。例如下面的語句將先前賦給ch的值作為字符打印出來:

putchar (ch);

該語句與下面的語句有同樣的效果: ?printf ("%c", ch); ? ? /*不打印換行符('\0')*/

注意: 它們不需要格式說明符,因為它們只對字符起作用。這兩個函數通常都在stdio.h文件中定義(而且他們通常只是預處理器宏(macro)),而不是真正的函數。

#include <stdio.h> int main (void) {char ch;int count = 0;while ((ch = getchar ()) != EOF && count++ < 10)putchar (ch);return 0; } 六、getchar()和scanf()混合使用

getchar()讀取每個字符,包括空格、制表符和換行符;而scanf()在讀取數字是則會跳過空格、制表符和換行符。因此他們不能很好的混合在一起。

例如:

#include <stdio.h> void display (char, int ,int); int main (void) {char ch;int n,m;printf ("enter a char: \n");//while ((ch = getchar ()) != '\n')while ((ch = getchar ()) != EOF){if (scanf ("%d%d", &n, &m) != 2)break;display (ch, n, m); #if 0while (getchar () != '\n')continue; #endifscanf ("%*[^\n]");scanf ("%*c");}return 0; }void display (char ch, int n, int m) {int row, col;for (row = 1; row <= n; row++){ for (col = 1; col <=m; col++)putchar (ch);printf ("\n");} } 七、輸入確認

兩個例子:

#include <stdio.h> int main (void) {int n;scanf ("%d", &n);printf ("%d\n", n < 0 ? n : (-n)); #if 0while (n >= 0){scanf ("%d", &n);}printf ("%d\n", n); #endifreturn 0; } #include <stdio.h> int main (void) {int n;char ch;while (scanf ("%d", &n) != 1){while ((ch = getchar ()) != '\n') putchar (ch);}return 0; } 輸入有字符組成,但scanf()可以將輸入轉換成整數或浮點值。使用想%d或%f這樣的說明符能限制可接受的輸入的字符類型,但getchar()和使用%c的scanf()接受任何字符。

八、字符串輸入

三種方法:

1、scanf()函數輸入

char *str1[20];

char *str2[20];

scanf ("%s %s", str1, str2);

str是已分配的20字節存儲塊的地址,也可以使用C庫里分配存儲空間的函數,如malloc()。

char *ptr = (*char)malloc (20*sizeof (char));

scanf()可以不僅可以讀取字符串還可以獲取單個字符。如果使用%s格式,字符串讀到(但不包括)下一個空白字符(比如空格、制表符或換行符)輸入結束。

scanf()函數返回一個整數值,這個值是成功讀取的項目數,或者當遇到文件結束時返回一個EOF(文件結尾符)。

#include <stdio.h> int main (void) {char n[12], m[11];scanf ("%5s %10s", n, m); /*指定輸出字段寬度,%5s,則scanf()就會讀入5個字符*/printf ("%s, %s\n", n, m);return 0; } 輸出結果: student stude, nt

2、gets()函數輸入

gets()函數從系統的標準輸入設備(通常是鍵盤)獲得一個字符串。因為字符串沒有預定的長度,所以gets()需要知道輸入何時結束。解決辦法是讀字符串直到遇到一個換行字符串(\n),按回車鍵可以產生這個字符。它將讀取換行符并將其丟棄,這樣下一次讀取就會在新的一行開始。它讀取換行符之前(不包括換行符)的所有字符,在這些字符后添加一個字符(\0),然后把這個字符交給調用它的程序。

gets()函數通過兩種方式獲得輸入:

A、它使用一個地址把字符串賦予name

B、gets()的代碼使用return關鍵字返回字符串的地址,程序把這個地址分配給ptr。注意到ptr是一個指針,這意味著gets()必須返回一個指向char的指針值。需要注意的是gets()返回的指針與傳遞給它的是同一個指針。輸入字符串只有一個備份,它放在作為函數參數傳遞過來的地址中。

#include <stdio.h> int main (void) {char name[50];char *ptr;while ((ptr = gets (name)) != NULL){printf ("name is %s\n", name);printf ("ptr is %s\n", ptr);break;}return 0; } 輸出結果: HELLO name is HELLO ptr is HELLO 3、fgets()函數輸入

fgets()是為文件I/O而設計的,它與gets()有三方面不同:

A、gets()不檢查預留存儲區是否能夠容納實際輸入的數據,多出來的字符簡單地溢出到相鄰的內存區。而fgets()函數可以在第二個參數來說明最大讀入字符數,如果這個參數值為n,fgets()就會讀取最多n-1個字符或者讀完一個換行符為止,由這二者最先滿足的那個來結束輸入。

B、如果fgets()讀取到換行符,就會把它存到字符串里,這樣每次顯示字符串時就會顯示換行符;而不是像gets()那樣丟棄它。

C、fgets()還需第三個參數來說明讀哪一個文件。從鍵盤上讀數據時,可以使用stdin(代表standard input)作為該參數,這個標識符在stdio.h中定義。

#include <stdio.h> int main (void) {char name [20];char *ptr;ptr = fgets (name, 20, stdin);printf ("%s?, hi %s!\n", name, ptr);return 0; } 輸出結果: JOY JOY ?, hi JOY !


去掉換行符:

#include <stdio.h> #include <string.h>int main (void) {char name[20];char *ptr;char *find;ptr = fgets (name, 20, stdin);find = strchr (name, '\n');if (find)*find = '\0';printf ("%s?,hi,%s!\n",ptr, name);return 0; } 輸出結果: Joy Joy?,hi,Joy!<strong> </strong>

九、字符串輸出

1、printf()函數輸出

printf ("%s, %s\n", name, str);

printf ()函數需要一個字符串地址作為參數,優點在于可以格式化多種數據類型。

2、puts()函數輸出

puts()函數只需要給出字符串參數的地址,每一個字符串都是單行顯示。與printf()不同,puts()顯示字符串時自動在其后添加一個換行符。當遇到空字符就會停止,必須確保有空字符(\0)存在。

#include <stdio.h> int main (void) {char code1[] = "haha!";char code[] = {'h','e','l','l','o',' ','w','o','r','l','d' };char code2[] = "show!";puts (code);return 0; } 輸出結果: hello worldhaha! 說明:code沒有空字符(\0),因此它是一個字符數組不是一個字符串,puts()函數將繼續執行直到遇到code2中的空字符。

3、fputs()函數輸出

fputs()函數需要第二個參數來說明要寫的文件??梢允褂胹tdout (代表 stdndard output)作為參數來進行輸出顯示,stdout在stdio.h中定義。與puts()不同,fputs()并不為輸出自動添加換行符。

注意:gets()丟掉輸入里的換行符,但是puts()為輸出添加換行符。fgets()存儲輸入中的換行符,而fputs不為輸出添加換行符。由此可見:

gets()和 puts()一起使用,fgets()和fputs()一起使用。

4、putcahr()函數輸出,擴展

#include <stdio.h> int put (const char *); /*使用const關鍵字*/ int main (void) {char arr[] = {'h', 'e', ' ' , 'l', 'l', 'o'}; /*區分空格符 ''*和空白符'\0'/char *ptr = arr;while (*ptr != '\0'){ /*等價于 while (*ptr)*/putchar (*ptr++);}putchar ('\n');printf ("I love you %d\n" ,("hello world!")); /*計算機先計算put()函數,所以先輸出hello world!*/return 0; } int put (const char *string) {int count = 0;while (*string){ putchar (*string++);count++; }putchar ('\n'); /*putchar不打印換行符*/return count; } 輸出結果: he llo hello world! I love you 12

十、文件輸入

1、getc ()函數輸入

函數功能:
從流中取字符
函數用法:
int getc(FILE *stream);

//read the next character from stream and return it as an unsigned char cast to a int ,or EOF on end of file or error.

注意: 此函數被ISO C聲明為一個宏,所以在用時不能將其做為函數指針傳(有一些編用時不能將其做為函數指針傳(有一些編譯器將其以函數形式也給另說)。

//示例 #include<stdio.h> int main() {char c;printf("請輸入字符:");c = getc(stdin);printf("輸入的字符:");putc(c, stdout);return(0); }

getc、fgetc、getchar函數區別:

//函數原型 #include <stdio.h> int getc(FILE *stream); int fgetc(FILE *stream); int getchar(void);

getchar ()函數從標準輸入(鍵盤)獲得一個字符:?

ch = getchar ( );

getc ()函數從fp指定的文件中獲得一個字符:

ch = getc (fp);

所以,ch = getc (stdin) 和 ch = getchar ( )的作用是一樣的。

參看:fgetc和getc的區別

兩個都是用來從stream中取得一個字符的,區別在于調用getc函數時所用的參數stream不能是有副作用的表達式,而fgetc函數則可以,也就是說,getc可以被當作宏來調用,而fgetc只能作為函數來調用。一般來說,調用宏比調用函數耗費的時間少。

擴展:有副作用的表達式,指的是表達式執行后,會改變表達式中某些變量的值?
最簡單的如++i,這個表達式執行后,i的值會改變,這樣的表達式是不應該在宏調用里出現的

//fgetc()示例 #include <stdio.h> int main(void) {FILE *fp;int c;fp = fopen("abc.txt", "r");while((c = fgetc(fp)) != EOF) {if (c == 'b') {putchar(c);}}fclose(fp);return 0; }


2、fprintf ()函數

fprintf ()的工作方式和printf()相似,區別在于前者需要第一個參數來指定合適的文件。

函數聲明:
int fprintf(FILE * stream, const char * format, ...);
函數說明:
fprintf()會根據參數format 字符串來轉換并格式化數據, 然后將結果輸出到參數stream 指定的文件中, 直到出現字符串結束('\0')為止。
返回值:
關于參數format 字符串的格式請參考printf(). 成功則返回實際輸出的字符數, 失敗則返回-1, 錯誤原因存于errno 中.
參數:
stream
-- 這是指向 FILE 對象的指針,該 FILE 對象標識了流。
format -- 這是 C 字符串,包含了要被寫入到流 stream 中的文本。它可以包含嵌入的 format 標簽,format 標簽可被隨后的附加參數中指定的值替換,并按需求進行格式化。

參看:C語言再學習 -- printf、scanf占位符

/*fprintf函數演示*/ #include <stdio.h> int main() {FILE *p_file = fopen("b.txt","w");if(p_file){// printf("%c,%g,%d\n",'c',3.14f,46); //打印在屏幕上fprintf(p_file,"%c,%g,%d\n",'c',3.14,46);//fprintf函數可以把數據按照格式記錄到文本文件中fclose(p_file);p_file=NULL;}return 0; }

十一、文件輸出

1、putc ()函數

函數功能:
用于輸入一個字符到指定流中
函數原型:
int putc(int ch, FILE *stream);
參數:
參數ch表示要輸入的位置,參數stream為要輸入的流。
返回值:
若正確,返回輸入的的字符,否則返回EOF。

//putc示例 #include <stdio.h> int main () {FILE *fp;int ch;fp = fopen("abc.txt", "w");for( ch = 33 ; ch <= 100; ch++ ) {putc(ch, fp);}fclose(fp);return(0); }//fgetc讀取 #include <stdio.h> int main () {FILE *fp;int c;fp = fopen("file.txt","r");while(1){c = fgetc(fp);if( feof(fp) ){break ;}printf("%c", c);}fclose(fp);return(0); }

putc與putchar的區別:

putchar函數,輸出到顯示器

putc函數,將字符輸入到文件

把stdout作為putc()函數的第二個參數。stdout是在stdout中定義的與標準輸出相關的文件指針,

所以putc (ch, stdout) 和 putchar ( )的作用是一樣的。

2、fscanf ()函數

fscanf ()的工作方式和scanf()相似,區別在于前者需要第一個參數來指定合適的文件。

函數聲明:
int fscanf(FILE *stream, const char *format, ...)
參數:
stream -- 這是指向 FILE 對象的指針,該 FILE 對象標識了流。
format -- 這是 C 字符串,包含了以下各項中的一個或多個:空格字符、非空格字符和format說明符。

參看:C語言再學習 -- printf、scanf占位符
返回值:

如果成功,該函數返回成功匹配和賦值的個數。如果到達文件末尾或發生讀錯誤,則返回 EOF。

/*fscanf函數演示*/ #include <stdio.h> int main() {char ch=0;float fnum=0.0;int num=0;FILE *p_file=fopen("b.txt","r");if(p_file){// scanf("%c%g%d",&ch,&fnum,&num);fscanf(p_file,"%c %g %d",&ch,&fnum,&num);//fscanf函數可以從文件中按照格式把數據拷貝到內存的存儲區里printf("%g %c %d\n",fnum,ch,num); //拷貝到存儲區我們就可以打印出來fclose(p_file);p_file=NULL;}return 0; }


總結

以上是生活随笔為你收集整理的C语言再学习 -- 输入/输出的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。