Fread 和fwrite的參數不同,返回值不同

函數fwrite

功能
??C語言函數,向文件寫入一個數據塊??。
size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);
注意:這個函數以二進制形式對文件進行操作,不局限于文本文件
返回值:返回實際寫入的數據塊數目
(1)buffer:是一個指針,對fwrite來說,是要輸出數據的地址;
(2)size:要寫入內容的單字節數;
(3)count:要進行寫入size字節的數據項的個數;
(4)stream:目標文件指針;
(5)返回實際寫入的數據項個數count。



剛才編一個關于用C庫函數實現的文件復制操作的代碼時發生錯誤。錯誤的根本是想當然的以為fread函數的用法,對其理解不深刻。后來在網友幫助下才發現錯誤。

其實函數的用法可以通過Linux中的man來獲得幫助。

比如fread.在終端鍵入

[cpp] view plaincopyprint?
  1. man?3?fread???
這是會出現下面的東西:
[cpp] view plaincopyprint?
  1. NAME??
  2. ???????fread,?fwrite?-?binary?stream?input/output??
  3. ??
  4. SYNOPSIS??
  5. ???????#include?<stdio.h>??
  6. ??
  7. ???????size_t?fread(void?*ptr,?size_t?size,?size_t?nmemb,?FILE?*stream);??
  8. ??
  9. ???????size_t?fwrite(const?void?*ptr,?size_t?size,?size_t?nmemb,??
  10. ?????????????????????FILE?*stream);??
  11. ??
  12. DESCRIPTION??
  13. ???????The?function?fread()?reads?nmemb?elements?of?data,?each?size?bytes?long,?from?the?stream?pointed?to?by?stream,?storing?them?at?the?location?given?by?ptr.??
  14. ??
  15. ???????The??function??fwrite()??writes??nmemb?elements?of?data,?each?size?bytes?long,?to?the?stream?pointed?to?by?stream,?obtaining?them?from?the?location?given?by??
  16. ???????ptr.??
  17. ??
  18. ???????For?nonlocking?counterparts,?see?unlocked_stdio(3).??
  19. ??
  20. RETURN?VALUE??
  21. ???????On?success,?fread()?and?fwrite()?return?the?number?of?items?read?or?written.??This?number?equals?the?number?of?bytes?transferred?only?when?size?is?1.??If?an??
  22. ???????error?occurs,?or?the?end?of?the?file?is?reached,?the?return?value?is?a?short?item?count?(or?zero).??
  23. ??
  24. ???????fread()?does?not?distinguish?between?end-of-file?and?error,?and?callers?must?use?feof(3)?and?ferror(3)?to?determine?which?occurred.??

重點放在對返回值。

可以看出,如果調用成功的話,函數會返回讀到的元素個數。如果想返回實際讀取的字節數的話只有當size=1,也就是第二個參數size為1時。如果發生讀取錯誤的話,或者已經到達文件末尾,返回值是一個小的元素個數值或者是0.下面給出我的代碼,正確實現文件拷貝的代碼,以此分析。

[cpp] view plaincopyprint?
  1. #include?<stdio.h>??
  2. ??
  3. #define?BUFFER_SIZE??1024??
  4. ??
  5. int?main(int?argc,?char?*argv[])??
  6. {??
  7. ????FILE?*from_fp,?*to_fp;??
  8. ????int?bytes_read,?bytes_write;??
  9. ????char?*ptr;??
  10. ????char?buffer[BUFFER_SIZE];??
  11. ??
  12. ????if(argc?!=?3)???????//參數包括源文件名與目標文件名??
  13. ????{??
  14. ????????printf("Input?failed!\n");??
  15. ????????return?1;??
  16. ????}??
  17. ??
  18. ????if(?(from_fp?=?fopen(argv[1],"r"))?==?NULL?)????//以只讀方式打開源文件名??
  19. ????{??
  20. ????????printf("File?is?not?exist\n");??
  21. ????????return?1;??
  22. ????}??
  23. ??????
  24. ????if((to_fp?=?fopen(argv[2],"w+"))?==?NULL)??????//打開第二個文件??
  25. ????{??
  26. ????????printf("Open?file?failed!\n");????
  27. ????????return?1;??
  28. ????}??
  29. ??
  30. ????while(bytes_read?=?fread(buffer,?1,?BUFFER_SIZE,?from_fp))??//讀取BUFFSIZE大小字節??
  31. ????{??
  32. ????????if(bytes_read?>?0)???????????//讀取有效數據??
  33. ????????{??
  34. ????????????ptr?=?buffer;??
  35. ????????????while(bytes_write?=?fwrite(ptr,?1,?bytes_read,?to_fp))??//寫數據到目標文件??
  36. ????????????{??
  37. ????????????????if(bytes_write?==?bytes_read)???????????//寫完??????
  38. ????????????????????break;??
  39. ????????????????else?if(bytes_write?>?0)?????????//未寫完??
  40. ????????????????{??
  41. ????????????????????ptr?+=?bytes_write;??
  42. ????????????????????bytes_read?-=?bytes_write;??
  43. ????????????????}??
  44. ????????????}??
  45. ????????????if(bytes_write?==?0)????????????//寫錯誤??
  46. ????????????????break;??
  47. ????????}??
  48. ????}??
  49. ??????
  50. ????fclose(from_fp);??
  51. ????fclose(to_fp);??
  52. ??
  53. ????return?0;??
  54. }??

意到我的fread和fwrite中的第二個參數size都是1,這樣的話我返回值就是實際讀取到的或寫入的字節數。剛開始我寫的程序不是這樣的,我是
[cpp] view plaincopyprint?
  1. while(bytes_read?=?fread(buffer,?BUFFER_SIZE,?1,from_fp))??
[cpp] view plaincopyprint?
  1. while(bytes_write?=?fwrite(ptr,?bytes_read,?1,?to_fp))??

這里第三個參數為1,換句話說,也就是說要讀取1個元素(返回值為1),此元素中包含BUFFER_SIZE個字節,因為我的文件不滿足這個條件,這樣的元素值不存在。于是返回的值為0,這也是為什么我的文件數據沒有復制到另一個文件的原因了,因為根本就沒有執行這個循環中的代碼。

另外一個需要注意到的問題是fread函數不能區分文件是否結尾和出錯兩種情況。所以必須使用ferror()和feof()函數來確定到底是哪種情況,所以關于文件復制還有下面另一種寫法。代碼如下:

[cpp] view plaincopyprint?
  1. #include?<stdio.h>??
  2. #include?<string.h>??
  3. ??
  4. #define?BUFFER_SIZE??1024??
  5. ??
  6. int?main(int?argc,?char?*argv[])??
  7. {??
  8. ????FILE?*from_fp,?*to_fp;??
  9. ????//int?bytes_read,?bytes_write;??
  10. ????long?file_len?=?0;??
  11. ????char?buffer[BUFFER_SIZE];??
  12. ??
  13. ????if(argc?!=?3)???????//參數包括源文件名與目標文件名??
  14. ????{??
  15. ????????printf("Input?failed!\n");??
  16. ????????return?1;??
  17. ????}??
  18. ??
  19. ????if(?(from_fp?=?fopen(argv[1],"r"))?==?NULL?)????//以只讀方式打開源文件名??
  20. ????{??
  21. ????????printf("File?is?not?exist\n");??
  22. ????????return?1;??
  23. ????}??
  24. ??????
  25. ????if((to_fp?=?fopen(argv[2],"w+"))?==?NULL)??????//打開第二個文件??
  26. ????{??
  27. ????????printf("Open?file?failed!\n");????
  28. ????????return?1;??
  29. ????}??
  30. ??????
  31. ????fseek(from_fp,?0L,?SEEK_END);???????//定位文件指針到尾部??
  32. ????file_len?=?ftell(from_fp);??????????//獲得文件長度??
  33. ????fseek(from_fp,?0L,?SEEK_SET);???????//定位文件指針到開始處??
  34. ??
  35. ????while(!feof(from_fp))???????????????//判斷文件是否結束??
  36. ????{??
  37. ????????fread(buffer,?BUFFER_SIZE,?1,?from_fp);??
  38. ????????if(BUFFER_SIZE?>?file_len)???????????????//緩沖區長度大于文件長度??
  39. ????????????fwrite(buffer,?file_len,?1,?to_fp);??
  40. ????????else??????????????????????????????????
  41. ????????{??
  42. ????????????fwrite(buffer,?BUFFER_SIZE,?1,?to_fp);??
  43. ????????????file_len?-=?BUFFER_SIZE;??
  44. ????????}??
  45. ????????bzero(buffer,BUFFER_SIZE);??????//清零緩沖區??
  46. ????}??
  47. ??
  48. ????fclose(from_fp);??
  49. ????fclose(to_fp);??
  50. ??
  51. ????return?0;??
  52. }??

這里面多了幾個函數,其中feof就是用來檢測文件是否結尾的函數。其返回值非0時表示文件結束。還有一個函數bzero是清零一段緩沖區的函數,使用需包含頭文件string.h。注意fread和fwrite函數的書寫就是采用第三個參數為1的方式來書寫的了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/253063.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/253063.shtml
英文地址,請注明出處:http://en.pswp.cn/news/253063.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

課程簡介及算法分析

先學課程 -概率論 運行時間&#xff08;running time&#xff09; - 輸入&#xff08;eg 已經排序&#xff09; - 輸入規模&#xff08;6和6*10^9&#xff09; 各種各樣的分析&#xff1a; - 最壞情況分析&#xff08;worst case&#xff09;usually T(n) max time when inp…

利用shell腳本添加環境變量

在shell腳本設置了環境變量&#xff0c;如export LIBRARY_PATH./lib/&#xff0c;執行了此腳本后, 在執行生成的可執行文件&#xff0c;提示錯誤 error while loading shared libraries: libww.so: cannot open shared object file: No such file or directory 但是如果把expor…

2017 ACM-ICPC西安網賽B-Coin

B-Coin Bob has a not even coin, every time he tosses the coin, the probability that the coins front face up is \frac{q}{p}(\frac{q}{p} \le \frac{1}{2})?p??q??(?p??q??≤?2??1??). The question is, when Bob tosses the coin kktimes, whats the pr…

Java第四次作業

Dog dognew Dog("哈士奇","黑白",2);System.out.println(dog);}}class Dog {private String name;private String color;private int age;public String getName(){return name;}public String getColor(){return color;}public int getAge(){return age;}…

ITU-RBT.656視頻標準接口

601是SDTV的數據結構 656是SDTV的interface 709是HDTV的數據結構 1120是HDTV的interface ITU-R BT.601是演播室數字電視編碼參數標準&#xff0c;而ITU-R BT.656 則是ITU-R BT.601附件A中的數字接口標準&#xff0c; 用于主要數字視頻設備(包括芯片)之間采用27Mhzs并口或243Mb…

C語言博客作業03--函數

1.本章學習總結 1.1思維導圖 1.2本章學習體會及代碼量學習體會 1.2.1學習體會 本周學習了函數&#xff0c;其實&#xff0c;函數于之前學習的三大控制結構是密不可分的&#xff0c;而函數又有其特殊的地方&#xff0c;例如&#xff1a;函數的聲明、函數的調用等等。我們之前編寫…

Shell記錄-Shell命令(其他)

top命令是Linux下常用的性能分析工具&#xff0c;能夠實時顯示系統中各個進程的資源占用狀況&#xff0c;類似于Windows的任務管理器。 &#xff0e;命令格式 top [參數]Shell2&#xff0e;命令功能 顯示當前系統正在執行的進程的相關信息&#xff0c;包括進程ID、內存占用率、…

Insta360:從軟到硬,一年做出360°全景相機,中間填了多少坑?

摘要劉靖康在大學就開始創業。在大二的時候他曾經去騰訊實習&#xff0c;然后又去了“超級課程表”這個團隊實習半年&#xff0c;2013 年 9 月回到南京創業&#xff0c;一開始的產品叫“名校直播”&#xff0c;是一款圍繞院校名師講座所做的視頻直播產品。 不久前&#xff0c;一…

No.10 awk、變量、運算符、if多分支

awk、變量、運算符、if多分支 awk語法 ~ awk -F: {print $3,$4} /etc/passwd //-F指定:分隔符 默認以空格作為分隔符 ~ awk -F: {print &0,NF} //$0打印全部,NF有幾段內容 ~ awk -F: {print $NF} /etc/passwd //$NF打印最后一段內容 ~ awk -F: {print NR} /etc/passwd…

什么是自然語言處理技術

自然語言處理&#xff08;NLP&#xff09;是計算機科學&#xff0c;人工智能&#xff0c;語言學關注計算機和人類&#xff08;自然&#xff09;語言之間的相互作用的領域。自然語言處理是計算機科學領域與人工智能領域中的一個重要方向。它研究能實現人與計算機之間用自然語言進…

SDOI2005 區間

題目描述 現給定n個閉區間[ai, bi]&#xff0c;1<i<n。這些區間的并可以表示為一些不相交的閉區間的并。你的任務就是在這些表示方式中找出包含最少區間的方案。你的輸出應該按照區間的升序排列。這里如果說兩個區間[a, b]和[c, d]是按照升序排列的&#xff0c;那么我們有…

排序: 選擇排序

1. 基本原理 將待排序的元素分為已排序(初始為空)和未排序兩組&#xff0c;依次將未排序的元素中值最小的元素放入已排序的組中。 直接選擇排序簡單直觀&#xff0c;但性能略差&#xff1b;堆排序是一種較高效的選擇排序方法&#xff0c;但實現起來略微復雜。 2. 直接選擇排序 …

JavaScript的值傳遞和引用傳遞

原文: Explaining Value vs. Reference in Javascript譯者: Fundebug為了保證可讀性&#xff0c;本文采用意譯而非直譯。另外&#xff0c;本文版權歸原作者所有&#xff0c;翻譯僅用于學習。 JavaScript有5種基本的數據類型&#xff0c;分別是&#xff1a;布爾、null、undefine…

全景攝像技術大有可為

網絡攝像機發展至今&#xff0c;已經基本滿足了“高清”、“日夜監控”、“遠距離監控”的需求&#xff0c;但是 隨著細分市場的發展&#xff0c;超廣角攝像機需求逐漸凸顯出來。主要應用在會議室、辦公室、大廳/大堂、商場、倉庫、車間等大面積開闊的區域&#xff0c;解決原來…

C#編程(五十三)----------字典DictionaryTKey,TValue

字典 關鍵字:Dicitionary 說明: 必須包含命名空間System.Collection.Generic Dictionary里面的每一個元素都是一個鍵值對(由兩個元組組成:鍵和值). 鍵必須是唯一的,而值不需要唯一的. 鍵和值都可以是任意類型(例如:string,int,自定義類型,等等) 通過一個鍵讀取一個值的事件是接…

setInterval只執行一次的原因

1 setInterval(arrow(),2000) 改為&#xff1a; 1 setInterval(arrow,2000) 原因&#xff1a; arrow()這是一個函數調用&#xff0c;函數調用就會有返回值&#xff0c; 而arrow()沒有返回值&#xff0c;所以這里的arrow()是一個undefined&#xff0c;自然你想要的循環執行arrow…

java文件傳輸之文件編碼和File類的使用

---恢復內容開始--- 我們知道&#xff0c;在用戶端和服務端之間存在一個數據傳輸的問題&#xff0c;例如下載個電影、上傳個照片、發一條訊息。在這里我們 就說一下文件的傳輸。 1.文件編碼 相信大家小時候玩過積木&#xff08;沒玩過也看過吧&#xff09;&#xff0c;看到一個…

Android 模擬輸入那點事

因工作原因&#xff0c;需要用到模擬輸入這個東東&#xff0c;查閱了一些資料&#xff0c;實現方式有多種&#xff0c;我大概分為兩類&#xff0c;命令行類和程序類。 命令行類包括自動化測試組件monkeyrunner&#xff0c;getevent/setevent命令&#xff0c;input命令 程序類包…

arm-linux-gcc:Command not found的問題

標簽&#xff1a; ubuntulinux 2015-05-15 10:47 680人閱讀 評論(0) 收藏 舉報 分類&#xff1a; Ubuntu&#xff08;23&#xff09; /etc/profile gcc&#xff08;9&#xff09; ARM匯編指令&#xff08;4&#xff09; 折騰了一天&#xff0c;終于搞定了。 ubuntu沒有roo…

[No0000111]java9環境變量配置bat

保存成bat&#xff08;utf-8 無簽名 編碼&#xff09; 右鍵以管理員權限運行 修改JAVAINSTALLPATH 為JAVA SDK 安裝目錄&#xff08;默認用C:\PROGRAM FILES\JAVA\&#xff09;即可&#xff1b; 只在 用戶變量下 創建&#xff0c;會事先保存好用戶原有的“JAVA_HOME,JRE_HOME,P…