|
常用鏈接
留言簿(3)
隨筆分類(lèi)
隨筆檔案
Friends
My Links
搜索
最新隨筆
最新評(píng)論

閱讀排行榜
評(píng)論排行榜
Powered by: 博客園
模板提供:滬江博客
|
|
|
|
|
發(fā)新文章 |
|
|
#include<iostream> #include<cstring> #include<cassert> #include<iomanip>
using namespace std; class String; istream& operator>>(istream&, String&); ostream& operator<<(ostream&,const String&);
class String { public: ?//構(gòu)造函數(shù) ?//String s1(); ?//String s1("abc"); ?//String s2(s1); ?String(); ?String(const char*); ?String(const String&); ?//析構(gòu)函數(shù) ?~String(); ?//賦值操作 ?String& operator=(const char*); ?String& operator=(const String&); ?//等于操作 ?bool operator==(const char*); ?bool operator==(const String&); ?//加操作 ?String operator+(const String&) const; ?//下標(biāo)操作 ?char& operator[](int); ?//成員操作 ?int size(){return _size;} ?char* c_str(){return _string;} ?//記數(shù)操作 ?int count(const char) const; private: ?int? _size; ?char *_string; };
inline String::String()??????????????????????????????????? //構(gòu)造函數(shù) { ?_size=0; ?_string=0; }
inline String::String(const char* str)???????????????????? //構(gòu)造函數(shù) { ?if(!str) ?{ ??_size=0; ??_string=0; ?} ?else ?{ ??_size=strlen(str); ??_string=new char[_size+1]; ??strcpy(_string,str); ?} }
inline String::String(const String& str)????????????????? //拷貝構(gòu)造函數(shù) { ?if(!str._size) ?{ ??_size=0; ??_string=0; ?} ?else ?{ ??_size=strlen(str._string); ??_string=new char[_size+1]; ??strcpy(_string,str._string); ?} }
inline String::~String()????????????????????????????????? //析構(gòu)函數(shù) { ?delete[] _string; }
inline String& String::operator=(const char* str)???????? //賦值操作 { ?if(!str) ?{ ??_size=0; ??delete[] _string; ??_string=0; ?} ?else ?{ ??_size=strlen(str); ??delete[] _string; ??_string=new char[_size+1]; ??strcpy(_string,str); ?} ?return *this; }
inline String& String::operator=(const String &str)????? //賦值操作 { ?if(this!=&str) ?{ ??_size=str._size; ??delete[] _string; ??_string=new char[_size+1]; ??strcpy(_string,str._string); ?} ?return *this; }
inline bool String::operator==(const String &rhs)????????? //等于操作符重載 { ?if(_size!=rhs._size) ??return false; ?return strcmp(_string,rhs._string)?false:true; }
inline bool String::operator==(const char *str)??????????? //等于操作符重載 { ?return strcmp(_string,str)?false:true; }
inline char& String::operator[](int n)???????????????????? //下標(biāo)訪(fǎng)問(wèn)符 { ?assert(n>=0 && n<_size); ?return _string[n]; }
inline int String::count(const char s) const?????????????? //記數(shù)操作 { ?int tempCount=0; ?for(int i=0;i<_size;i++) ?{ ??? ?if(_string[i]==s) ???++tempCount; ?} ?return tempCount; }
inline String String::operator+(const String& str) const? //加操作 { ?String tempStr; ?tempStr._size=_size+str._size; ?tempStr._string=new char[tempStr._size+1]; ?strcpy(tempStr._string,_string); ?strcat(tempStr._string,str._string); ?return tempStr; }
inline istream& operator>>(istream &io,String &str)?????? //輸入流 { ?const int limit_string_size =4096; ?char inBuf[limit_string_size]; ?io>>setw(limit_string_size)>>inBuf; ?str=inBuf; ?return io; }
inline ostream& operator<<(ostream &os,String &str)?????? //輸出流 { ?return os<<str.c_str(); }
int main() { ?String str1="abc"; ?String str2="def"; ?str1.size(); ?cout<<"size :"<<str1.size()<<endl; ?cout<<"b count :"<<str1.count('b')<<endl; ?String str3=str1+str2; ?cout<<str3;????? //該處不能為String&,只能為String。見(jiàn)String operator+()和ostream& operator<<(ostream &os,String &str) ?return 0; }
SO GOOD!
對(duì)于文字常量,列出如下關(guān)鍵信息,都是以前自己不太清楚的部分 文字常量類(lèi)型: 1、整型 2、浮點(diǎn)型 3、bool型 4、字符型 5、字符串型 6、轉(zhuǎn)移序列 =========================================== 1、整型:有short,int,long int。默認(rèn)情況下都是有符號(hào)型的:1024。最左邊為符號(hào)位,1表示負(fù)數(shù),0表示正數(shù)。如果要表示無(wú)符號(hào)型,則為:1024U。如果要表示長(zhǎng)整型,則為:1024L。 2、浮點(diǎn)型:默認(rèn)情況下都是double型的:3.141592。如果要表示為float型,則為3.141592F。如果要表示長(zhǎng)雙精度(即擴(kuò)展精度),則為3.141592L。 4、字符型:'A' ,數(shù)據(jù)類(lèi)型為char。L'A' 為寬字符型,數(shù)據(jù)類(lèi)型wchar_t。 5、字符串型:"hello,world",數(shù)據(jù)類(lèi)型為const常量數(shù)組。特別需要注意的是:編譯后的字符串長(zhǎng)度=編譯前的字符串長(zhǎng)度+編譯器為表示字串結(jié)束而自動(dòng)為其在最后位加入的NULL(即'\0'),這在字符型里是不會(huì)出現(xiàn)的。 L"hello,world":寬字符串型。 6、轉(zhuǎn)移序列: 常見(jiàn)的有\(zhòng)"(雙引號(hào))? \'(單引號(hào)) \\(反斜杠)等 (自己太懶了,都不想寫(xiě)了)
對(duì)于1、2有特別需要注意的地方,有符號(hào)型的只能是整型數(shù)據(jù),不能用在浮點(diǎn)型上。 如果要讓一行未結(jié)束的字串換行繼續(xù)寫(xiě),則可以用如下表示: "hello?,my \ ?girlfirend" 也就是說(shuō),要在最后一個(gè)字符后面加"\"反斜杠。
? 鍵盤(pán)、顯示器、打印機(jī)、磁盤(pán)驅(qū)動(dòng)器等邏輯設(shè)備, 其輸入輸出都可以通過(guò)文 件管理的方法來(lái)完成。而在編程時(shí)使用最多的要算是磁盤(pán)文件, 因此本節(jié)主要以 磁盤(pán)文件為主, 詳細(xì)介紹Turbo C2.0提供的文件操作函數(shù), 當(dāng)然這┒暈?zāi)件的? 作函數(shù)也適合于非磁盤(pán)文件的情況。 ??? 另外, Turbo C2.0提供了兩類(lèi)關(guān)于文件的函數(shù)。一類(lèi)稱(chēng)做標(biāo)準(zhǔn)文件函數(shù)也稱(chēng) 緩沖型文件函數(shù), 這是ANSI標(biāo)準(zhǔn)定義的函數(shù); 另一類(lèi)叫非標(biāo)準(zhǔn)文件函數(shù), 也稱(chēng)非 緩沖型文件函數(shù)。這類(lèi)函數(shù)最早公用于UNIX操作系統(tǒng), 但現(xiàn)在MS-DOS3.0 以上版 本的操作系統(tǒng)也可以使用。下面分別進(jìn)行介紹。 ? ??? 1.2.1? 標(biāo)準(zhǔn)文件函數(shù) ??? 標(biāo)準(zhǔn)文件函數(shù)主要包括文件的打開(kāi)、關(guān)閉、讀和寫(xiě)等函數(shù)。不象BASIC 、 FORTRAN語(yǔ)方有順序文件和隨機(jī)文件之分,?? 在打開(kāi)時(shí)就應(yīng)按不同的方式確定。 Turbo C2.0并不區(qū)分這兩種文件, 但提供了兩組函數(shù), 即順序讀寫(xiě)函數(shù)和隨機(jī)讀 寫(xiě)函數(shù)。 ??? 一、文件的打開(kāi)和關(guān)閉 ??? 任何一個(gè)文件在使用之前和使用之后, 必須要進(jìn)行打開(kāi)和關(guān)閉, 這是因?yàn)椴? 作系統(tǒng)對(duì)于同時(shí)打開(kāi)的文件數(shù)目是有限制的, DOS操作系統(tǒng)中,??? 可以在DEVICE .SYS中定義允許同時(shí)打開(kāi)的文件數(shù)n(用files=n定義)。其中n 為可同時(shí)打開(kāi)的文 件數(shù), 一般n<=20。因此在使用文件前應(yīng)打開(kāi)文件, 才可對(duì)其中的信息進(jìn)行存取。 用完之后需要關(guān)閉, 否則將會(huì)出現(xiàn)一些意想不到的錯(cuò)誤。Turbo C2.0提供了打開(kāi) 和關(guān)閉文件的函數(shù)。
??? 1. fopen()函數(shù) ??? fopen函數(shù)用于打開(kāi)文件, 其調(diào)用格式為: ???? FILE *fopen(char *filename, *type); ??? 在介紹這個(gè)函數(shù)之;前, 先了解一下下面的知識(shí)。 ??? (1) 流(stream)和文件(file) ??? 流和文件 在Turbo C2.0中是有區(qū)別的, Turbo C2.0 為編程者和被訪(fǎng)問(wèn)的設(shè) 備之間提供了一層抽象的東西, 稱(chēng)之為"流", 而將具體的實(shí)際設(shè)備叫做文件。 流是一個(gè)邏輯設(shè)備, 具有相同的行為。因此, 用來(lái)進(jìn)行磁盤(pán)文件寫(xiě)的函數(shù)也同樣 可以用來(lái)進(jìn)行打印機(jī)的寫(xiě)入。在Turbo C2.0中有兩種性質(zhì)的流:?? 文字流( text stream)和二進(jìn)制(binary stream)。對(duì)磁盤(pán)來(lái)說(shuō)就是文本文件和二進(jìn)制文件。本 軟件為了便于讓讀者易理解Turbo C2.0語(yǔ)言而沒(méi)有對(duì)流和文件作特別區(qū)分。 ??? (2) 文件指針FILE ??? 實(shí)際上FILE是一個(gè)新的數(shù)據(jù)類(lèi)型。它是Turbo C2.0的基本數(shù)據(jù)類(lèi)型的集合, 稱(chēng)之為結(jié)構(gòu)指針。有關(guān)結(jié)構(gòu)的概念將在第四節(jié)中詳細(xì)介紹, 這里只要將FILE理解 為一個(gè)包括了文件管理有關(guān)信息的數(shù)據(jù)結(jié)構(gòu), 即在打開(kāi)文件時(shí)必須先定義一個(gè)文 件指針。 ??? (3) 以后介紹的函數(shù)調(diào)用格式將直接寫(xiě)出形式參數(shù)的數(shù)據(jù)類(lèi)型和函數(shù)返回值 的數(shù)據(jù)類(lèi)型。例如: 上面打開(kāi)文件的函數(shù), 返回一個(gè)文件指針, 其中形式參數(shù)有 兩個(gè), 均為字符型變量(字符串?dāng)?shù)組或字符串指針)。本軟件不再對(duì)函數(shù)的調(diào)用格 式作詳細(xì)說(shuō)明。 ??? 現(xiàn)在再來(lái)看打開(kāi)文件函數(shù)的用法。 ??? fopen()函數(shù)中第一個(gè)形式參數(shù)表示文件名, 可以包含路徑和文件名兩部分。 如: ???? "B:TEST.DAT" ???? "C:\\TC\\TEST.DAT" ??? 如果將路徑寫(xiě)成"C:\TC\TEST.DAT"是不正確的, 這一點(diǎn)要特別注意。 ??? 第二個(gè)形式參數(shù)表示打開(kāi)文件的類(lèi)型。關(guān)于文件類(lèi)型的規(guī)定參見(jiàn)下表。 ?????????????????????? 表? 文件操作類(lèi)型 ??? ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ????????? 字符??????????????? 含義 ??? ──────────────────────────── ?????????? "r"?????????? 打開(kāi)文字文件只讀 ?????????? "w"?????????? 創(chuàng)建文字文件只寫(xiě) ?????????? "a"?????????? 增補(bǔ), 如果文件不存在則創(chuàng)建一個(gè) ?????????? "r+"????????? 打開(kāi)一個(gè)文字文件讀/寫(xiě) ?????????? "w+"????????? 創(chuàng)建一個(gè)文字文件讀/寫(xiě) ?????????? "a+"????????? 打開(kāi)或創(chuàng)建一個(gè)文件增補(bǔ) ?????????? "b"?????????? 二進(jìn)制文件(可以和上面每一項(xiàng)合用) ?????????? "t"?????????? 文這文件(默認(rèn)項(xiàng)) ??? ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ??? 如果要打開(kāi)一個(gè)CCDOS子目錄中, 文件名為CLIB的二進(jìn)制文件, 可寫(xiě)成: ???? fopen("c:\\ccdos\\clib", "rb"); ??? 如果成功的打開(kāi)一個(gè)文件, fopen()函數(shù)返回文件指針,?? 否則返回空指針 (NULL)。由此可判斷文件打開(kāi)是否成功。 ??? 2. fclose()函數(shù) ??? fclose()函數(shù)用來(lái)關(guān)閉一個(gè)由fopen()函數(shù)打開(kāi)的文件 , 其調(diào)用格式為: ????? int fclose(FILE *stream); ??? 該函數(shù)返回一個(gè)整型數(shù)。當(dāng)文件關(guān)閉成功時(shí), 返回0, 否則返回一個(gè)非零值。 可以根據(jù)函數(shù)的返回值判斷文件是否關(guān)閉成功。 ??? 例10: ???? #iclude<stdio.h> ???? main() ???? { ????????? FILE *fp;??????????????? /*定義一個(gè)文件指針*/ ????????? int i; ????????? fp=fopen("CLIB", "rb");? /*打開(kāi)當(dāng)前目錄名為CLIB的文件只讀*/ ????????? if(fp==NULL)???????????? /*判斷文件是否打開(kāi)成功*/ ???????????? puts("File open error");/*提示打開(kāi)不成功*/ ????????? i=fclose(fp);??????????? /*關(guān)閉打開(kāi)的文件*/ ????????? if(i==0)???????????????? /*判斷文件是否關(guān)閉成功*/ ??????????? printf("O,K");???????? /*提示關(guān)閉成功*/ ????????? else ??????????? puts("File close error");/*提示關(guān)閉不成功*/ ???? }
??? 二、有關(guān)文件操作的函數(shù) ??? 本節(jié)所講的文件讀寫(xiě)函數(shù)均是指順序讀寫(xiě), 即讀寫(xiě)了一條信息后, 指針自動(dòng) 加1。下面分別介紹寫(xiě)操作函數(shù)和讀操作函數(shù)。
??? 1. 文件的順序?qū)懞瘮?shù) ??? fprintf()、fputs()和fputc()函數(shù) ??? 函數(shù)fprintf()、fputs()和fputc()均為文件的順序?qū)懖僮骱瘮?shù),? 其調(diào)用格 式如下: ??? int fprintf(FILE *stream, char *format, <variable-list>); ??? int fputs(char *string, FILE *steam); ??? int fputc(int ch, FILE *steam); ??? 上述三個(gè)函數(shù)的返回值均為整型量。fprintf() 函數(shù)的返回值為實(shí)際寫(xiě)入文 件中的字罕個(gè)數(shù)(字節(jié)數(shù))。如果寫(xiě)錯(cuò)誤, 則返回一個(gè)負(fù)數(shù), fputs()函數(shù)返回0時(shí) 表明將string指針?biāo)傅淖址畬?xiě)入文件中的操作成功, 返回非0時(shí),? 表明寫(xiě)操 作失敗。fputc()函數(shù)返回一個(gè)向文件所寫(xiě)字符的值, 此時(shí)寫(xiě)操作成功,? 否則返 回EOF(文件結(jié)束結(jié)束其值為-1, 在stdio.h中定義)表示寫(xiě)操作錯(cuò)誤。 ???? fprintf( ) 函數(shù)中格式化的規(guī)定與printf( ) 函數(shù)相同,?? 所不同的只是 fprintf()函數(shù)是向文件中寫(xiě)入。而printf()是向屏幕輸出。 ??? 下面介紹一個(gè)例子, 運(yùn)行后產(chǎn)后一個(gè)test.dat的文件。 ??? 例11: ???? #include<stdio.h> ???? main() ???? { ????????? char *s="That's good news");? /*定義字符串指針并初始化*/ ????????? int i=617;??????????????????? /*定義整型變量并初始化*/ ????????? FILE *fp;???????????????????? /*定義文件指針*/ ????????? fp=fopne("test.dat", "w");??? /*建立一個(gè)文字文件只寫(xiě)*/ ????????? fputs("Your score of TOEFLis", fp);/*向所建文件寫(xiě)入一串字符*/ ????????? fputc(':', fp);?????????????? /*向所建文件寫(xiě)冒號(hào):*/ ????????? fprintf(fp, "%d\n", i);?????? /*向所建文件寫(xiě)一整型數(shù)*/ ????????? fprintf(fp, "%s", s);???????? /*向所建文件寫(xiě)一字符串*/ ????????? fclose(fp);?????????????????? /*關(guān)閉文件*/ ???? } ??? 用DOS的TYPE命令顯示TEST.DAT的內(nèi)容如下所示: ??? 屏幕顯示 ????? Your score of TOEFL is: 617 ????? That's good news
??? 2. 文件的順序讀操作函數(shù) ??? fscanf()、fgets()和fgetc()函數(shù) ??? 函數(shù)fscanf()、fgets()和fgetc()均為文件的順序讀操作函數(shù), 其調(diào)用格式 如下: ???? int fscanf(FILE *stream, char *format, <address-list>); ???? char fgets(char *string, int n, FILE *steam); ???? int fgetc(FILE *steam); ??? fscanf()函數(shù)的用法與scanf()函數(shù)相似,?? 只是它是從文件中讀到信息。 fscanf()函數(shù)的返回值為EOF(即-1), 表明讀錯(cuò)誤, 否則讀數(shù)據(jù)成功。fgets()函 數(shù)從文件中讀取至多n-1個(gè)字符(n用來(lái)指定字符數(shù)), 并把它們放入string指向的 字符串中, 在讀入之后自動(dòng)向字符串未尾加一個(gè)空字符, 讀成功返回string指針, 失敗返回一個(gè)空指針。fgetc()函數(shù)返回文件當(dāng)前位置的一個(gè)字符,? 讀錯(cuò)誤時(shí)返 回EOF。 ??? 下面程序讀取例11產(chǎn)生的test.dat文件, 并將讀出的結(jié)果顯示在屏幕上。 ??? 例12 ???? #include<stdio.h> ???? main() ???? { ????????? char *s, m[20]; ????????? int i; ????????? FILE? *fp; ????????? fp=fopen("test.dat", "r");??? /*打開(kāi)文字文件只讀*/ ????????? fgets(s, 24, fp);???????????? /*從文件中讀取23個(gè)字符*/ ????????? printf("%s", s);????????????? /*輸出所讀的字符串*/ ????????? fscanf(fp, "%d", &i);???????? /*讀取整型數(shù)*/ ????????? printf("%d", i);????????????? /*輸出所讀整型數(shù)*/ ????????? putchar(fgetc(fp));?????????? /*讀取一個(gè)字符同時(shí)輸出*/ ????????? fgets(m, 17, fp);???????????? /*讀取16個(gè)字符*/ ????????? puts(m);????????????????????? /*輸出所讀字符串*/ ????????? fclose(fp);?????????????????? /*關(guān)閉文件*/ ????????? getch();????????????????????? /*等待任一鍵*/ ???? } ??? 運(yùn)行后屏幕顯示: ??? Your score of TOEFL is: 617 ??? That's good news ??? 如果將上例中fscanf(fp, "%d", &i)改為fscanf(fp, "%s", m),? 再將其后 的輸出語(yǔ)句改為printf("%s", m), 則可得出同樣的結(jié)果。由此可見(jiàn)Turbo C2. 0 中只要是讀文字文件, 則不論是字符還是數(shù)字都將按其ASCII值處理。 另外還要 說(shuō)明的一點(diǎn)就是fscanf()函數(shù)讀到空白符時(shí), 便自動(dòng)結(jié)束, 在使用時(shí)要特別注意。
??? 3. 文件的隨機(jī)讀寫(xiě) ??? 有時(shí)用戶(hù)想直接讀取文件中間某處的信息, 若用文件的順序讀寫(xiě)必須從文件 頭開(kāi)始直到要求的文件位置再讀, 這顯然不方便。Turbo C2.0提供了一組文件的 隨機(jī)讀寫(xiě)函數(shù), 即可以將文件位置指針定位在所要求讀寫(xiě)的地方直接讀寫(xiě)。 ??? 文件的隨機(jī)讀寫(xiě)函數(shù)如下: ??? int fseek (FILE *stream, long offset, int fromwhere); ??? int fread(void *buf, int size, int count, FILE *stream); ??? int fwrite(void *buf, int size, int count, FILE *stream); ??? long ftell(FILE *stream); ??? fseek()函數(shù)的作用是將文件的位置指針設(shè)置到從fromwhere開(kāi)始的第offset 字節(jié)的位置上, 其中fromwhere是下列幾個(gè)宏定義之一: ??? 文件位置指針起始計(jì)算位置fromwhere ━━━━━━━━━━━━━━━━━━━━━━━━━━━ ??? 符號(hào)常數(shù)??????? 數(shù)值?????????? 含義 ─────────────────────────── ??? SEEK_SET????????? 0??????? 從文件開(kāi)頭 ??? SEEK_CUR????????? 1??????? 從文件指針的現(xiàn)行位置 ??? SEEK_END????????? 2??????? 從文件末尾 ━━━━━━━━━━━━━━━━━━━━━━━━━━━ ??? offset是指文件位置指針從指定開(kāi)始位置(fromwhere指出的位置)跳過(guò)的字 節(jié)數(shù)。它是一個(gè)長(zhǎng)整型量, 以支持大于64K字節(jié)的文件。fseek()函數(shù)一般用于對(duì) 二進(jìn)制文件進(jìn)行操作。 ??? 當(dāng)fseek()函數(shù)返回0時(shí)表明操作成功, 返回非0表示失敗。 ??? 下面程序從二進(jìn)制文件test_b.dat中讀取第8個(gè)字節(jié)。 ??? 例13: ???? #include<stdio.h> ???? main() ???? { ????????? FILE *fp; ????????? if((fp=fopen("test_b.dat", "rb"))==NULL) ??????????? { ????????????? printf("Can't open file"); ????????????? exit(1); ??????????? } ????????? fseek(fp, 8. 1, SEEK_SET); ????????? fgetc(fp); ????????? fclose(fp); ???? } ??? fread()函數(shù)是從文件中讀count個(gè)字段, 每個(gè)字段長(zhǎng)度為size個(gè)字節(jié), 并把 它們存放到buf指針?biāo)傅木彌_器中。 ??? fwrite()函數(shù)是把buf指針?biāo)傅木彌_器中, 長(zhǎng)度為size個(gè)字節(jié)的count個(gè)字 段寫(xiě)到stream指向的文件中去。 ??? 隨著讀和寫(xiě)字節(jié)數(shù)的增大, 文件位置指示器也增大, 讀多少個(gè)字節(jié), 文件位 置指示器相應(yīng)也跳過(guò)多少個(gè)字節(jié)。讀寫(xiě)完畢函數(shù)返回所讀和所寫(xiě)的字段個(gè)數(shù)。 ??? ftell()函數(shù)返回文件位置指示器的當(dāng)前值,? 這個(gè)值是指示器從文件頭開(kāi)始 算起的字節(jié)數(shù), 返回的數(shù)為長(zhǎng)整型數(shù), 當(dāng)返回-1時(shí), 表明出現(xiàn)錯(cuò)誤。 ??? 下面程序把一個(gè)浮點(diǎn)數(shù)組以二進(jìn)制方式寫(xiě)入文件test_b.dat中。 ??? 例14: ???? #include <stdio.h> ???? main() ???? { ????????? float f[6]={3.2, -4.34, 25.04, 0.1, 50.56, 80.5}; ???????????????????????? /*定義浮點(diǎn)數(shù)組并初始化*/ ????????? int i; ????????? FILE *fp; ????????? fp=fopen("test_b.dat", "wb"); /*創(chuàng)建一個(gè)二進(jìn)制文件只寫(xiě)*/ ????????? fwrite(f, sizeof(float), 6, fp);/*將6個(gè)浮點(diǎn)數(shù)寫(xiě)入文件中*/ ????????? fclose(fp);?????????????????? /*關(guān)閉文件*/ ???? } ??? 下面例子從test_b.dat文件中讀100個(gè)整型數(shù), 并把它們放到dat數(shù)組中。 ??? 例15: ???? #include <stdio.h> ???? main() ???? { ????????? FILE *fp; ????????? int dat[100]; ????????? fp=fopen("test_b.dat", "rb");/*打開(kāi)一個(gè)二進(jìn)制文件只讀*/ ????????? if(fread(dat, sizeof(int), 100, fp)!=100) ??????????????????????????????????????? /*判斷是否讀了100個(gè)數(shù)*/ ??????????? { ?????????????? if(feof(fp)) ???????????????? printf("End of file"); /*不到100個(gè)數(shù)文件結(jié)束*/ ?????????????? else ???????????????? printf("Read error");? /*讀數(shù)錯(cuò)誤*/ ????????? fclose(fp);?????????????????? /*關(guān)閉文件*/ ???? } ??? 注意: ??? 當(dāng)用標(biāo)準(zhǔn)文件函數(shù)對(duì)文件進(jìn)行讀寫(xiě)操作時(shí), 首先將所讀寫(xiě)的內(nèi)容放進(jìn)緩沖區(qū), 即寫(xiě)函數(shù)只對(duì)輸出緩沖區(qū)進(jìn)行操作, 讀函數(shù)只對(duì)輸入緩沖區(qū)進(jìn)行操作。例如向一 個(gè)文件寫(xiě)入內(nèi)容, 所寫(xiě)的內(nèi)容將首先放在輸出緩沖區(qū)中, 直到輸出緩沖區(qū)存滿(mǎn)或 使用fclose()函數(shù)關(guān)閉文件時(shí), 緩沖區(qū)的內(nèi)容才會(huì)寫(xiě)入文件中。若無(wú)fclose() 函數(shù), 則不會(huì)向文件中存入所寫(xiě)的內(nèi)容或?qū)懭氲奈募?nèi)容不全。有一個(gè)對(duì)緩沖區(qū) 進(jìn)行刷新的函數(shù), 即fflush(), 其調(diào)用格式為: ??? int fflush(FILE *stream); ??? 該函數(shù)將輸出緩沖區(qū)的內(nèi)容實(shí)際寫(xiě)入文件中, 而將輸入緩沖區(qū)的內(nèi)容清除掉。
??? 4. feof()和rewind()函數(shù) ??? 這兩個(gè)函數(shù)的調(diào)用格式為: ???? int feof(FILE *stream); ???? int rewind(FILE *stream); ??? feof()函數(shù)檢測(cè)文件位置指示器是否到達(dá)了文件結(jié)尾,? 若是則返回一個(gè)非0 值, 否則返回0。這個(gè)函數(shù)對(duì)二進(jìn)制文件操作特別有用, 因?yàn)槎M(jìn)制文件中,? 文 件結(jié)尾標(biāo)志EOF也是一個(gè)合法的二進(jìn)制數(shù),? 只簡(jiǎn)單的檢查讀入字符的值來(lái)判斷文 件是否結(jié)束是不行的。如果那樣的話(huà), 可能會(huì)造成文件未結(jié)尾而被認(rèn)為結(jié)尾, 所 以就必須有feof()函數(shù)。 ??? 下面的這條語(yǔ)句是常用的判斷文件是否結(jié)束的方法。 ???? while(!feof(fp)) ??????? fgetc(fp); ??? while為循環(huán)語(yǔ)句, 將在下面介紹。 ??? rewind()函數(shù)用于把文件位置指示器移到文件的起點(diǎn)處, 成功時(shí)返回0,? 否 則, 返回非0值。 ?
??? 1.2.2? 非標(biāo)準(zhǔn)文件函數(shù) ??? 這類(lèi)函數(shù)最早用于UNIX操作系統(tǒng), ANSI標(biāo)準(zhǔn)未定義,?? 但有時(shí)也經(jīng)常用到, DOS 3.0以上版本支持這些函數(shù)。它們的頭文件為io.h。 ??? 一、文件的打開(kāi)和關(guān)閉 ??? 1. open()函數(shù) ??? open()函數(shù)的作用是打開(kāi)文件, 其調(diào)用格式為: ???? int open(char *filename, int access); ??? 該函數(shù)表示按access的要求打開(kāi)名為filename的文件, 返回值為文件描述字, 其中access有兩部分內(nèi)容: 基本模式和修飾符, 兩者用" "("或")方式連接。修 飾符可以有多個(gè), 但基本模式只能有一個(gè)。access的規(guī)定如表3-2。 ?????????????? 表 access的規(guī)定 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 基本模式??? 含義??? 修飾符???????? 含? 義 ──────────────────────────── O_RDONLY??? 只讀?? O_APPEND?? 文件指針指向末尾 O_WRONLY??? 只寫(xiě)?? O_CREAT??? 文件不存在時(shí)創(chuàng)建文件, ????????????????????????????? 屬性按基本模式屬性 O_RDWR????? 讀寫(xiě)?? O_TRUNC??? 若文件存在, 將其長(zhǎng)度 ????????????????????????????? 縮為0, 屬性不變 ?????????????????? O_BINARY?? 打開(kāi)一個(gè)二進(jìn)制文件 ?????????????????? O_TEXT???? 打開(kāi)一個(gè)文字文件 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ??? open()函數(shù)打開(kāi)成功, 返回值就是文件描述字的值(非負(fù)值), 否則返回-1。
??? 2. close()函數(shù) ??? close()函數(shù)的作用是關(guān)閉由open()函數(shù)打開(kāi)的文件, 其調(diào)用格式為: ???? int close(int handle); ??? 該函數(shù)關(guān)閉文件描述字handle相連的文件。
??? 二、讀寫(xiě)函數(shù) ??? 1. read()函數(shù) ??? read()函數(shù)的調(diào)用格式為: ???? int read(int handle, void *buf, int count); ??? read()函數(shù)從handle(文件描述字)相連的文件中, 讀取count個(gè)字節(jié)放到buf 所指的緩沖區(qū)中, 返回值為實(shí)際所讀字節(jié)數(shù), 返回-1表示出錯(cuò)。返回0 表示文件 結(jié)束。
??? 2. write()函數(shù) ??? write()函數(shù)的調(diào)用格式為: ???? int write(int handle, void *buf, int count); ??? write()函數(shù)把count個(gè)字節(jié)從buf指向的緩沖區(qū)寫(xiě)入與handle相連的文件中, 返回值為實(shí)際寫(xiě)入的字節(jié)數(shù)。 ? ??? 三、隨機(jī)定位函數(shù) ??? 1. lseek()函數(shù) ??? lseek()函數(shù)的調(diào)用格式為: ???? int lseek(int handle, long offset, int fromwhere); ??? 該函數(shù)對(duì)與handle相連的文件位置指針進(jìn)行定位, 功能和用法與fseek() 函 數(shù)相同。
??? 2. tell()函數(shù) ??? tell()函數(shù)的調(diào)用格式為: ???? long tell(int handle); ??? 該函數(shù)返回與handle相連的文件現(xiàn)生位置指針, 功能和用法與ftell()相同。
完美世界游戲可以說(shuō)代表這目前國(guó)內(nèi)完全自主研發(fā)的游行引擎的最高水品!先感嘆下,等會(huì)兒去玩下
這次在工作上分別遇到過(guò)strcpy、memset、memcpy,也在網(wǎng)絡(luò)上看到過(guò)一些關(guān)于三者區(qū)別的文章,羅列大概內(nèi)容如下: strcpy()來(lái)自C語(yǔ)言,在C++里得以保留。首先,要指明的是,C++里strcpy()里接受的參數(shù)是C-串,并非string,更不可能是其他類(lèi)型的數(shù)據(jù)。它表示一個(gè)字串的內(nèi)容拷貝到另一個(gè)字串。拷貝會(huì)在源字串里第一個(gè)'\0'時(shí)停止拷貝.
strcpy(目標(biāo)字串,源字串);
ex: char *temp1,*temp2="test"; strcpy(temp1,temp2);
memset()主要用于對(duì)一個(gè)內(nèi)存區(qū)域初始化。一般用在字符數(shù)組上,至少我現(xiàn)在工作上遇到的多為這樣的情況。
memset(目標(biāo)內(nèi)存空間,拷貝內(nèi)容,限制);
ex: char temp[30]; memset(temp,'\0',sizeof(temp)); 正如上面所見(jiàn),char temp[30]只是分配了一定的內(nèi)存空間給該字符數(shù)組,但并未初始化該內(nèi)存空間,即數(shù)組。所以,需要使用memset()來(lái)進(jìn)行初始化。
memcpy() 除了和strcpy()一樣能拷貝字串外,還可以拷貝其他任何類(lèi)型的數(shù)據(jù).
ex: int a[3],b[4]; b[4]={0,1,2,3}; memcpy(a,b,sizeof(a)); //若為sizeof(b),則會(huì)造成數(shù)組a[]內(nèi)存外溢
================================ 如下內(nèi)容為網(wǎng)絡(luò)“原版”內(nèi)容 Memset? 用來(lái)對(duì)一段內(nèi)存空間全部設(shè)置為某個(gè)字符,一般用在對(duì)定義的字符串進(jìn)行初始化為‘ ’或‘\0’;
例
:char a[100];memset(a, '\0', sizeof(a));
?
??? memset
可以方便的清空一個(gè)結(jié)構(gòu)類(lèi)型的變量或數(shù)組。
如:
struct sample_struct { ?char ? csName[16]; ?int ? ?iSeq; ?int ? ?iType; };
對(duì)于變量
struct sample_strcut ?stTest;
一般情況下,清空
stTest
的方法:
stTest.csName[0]='\0'; stTest.iSeq=0; stTest.iType=0;
用
memset
就非常方便:
memset(&stTest,0,sizeof(struct sample_struct));
如果是數(shù)組:
?struct sample_struct ? TEST[10];
則
memset(TEST,0,sizeof(struct sample_struct)*10);
memcpy?
用來(lái)做內(nèi)存拷貝,你可以拿它拷貝任何數(shù)據(jù)類(lèi)型的對(duì)象,可以指定拷貝的數(shù)據(jù)長(zhǎng)度。
例:
char a[100],b[50]; memcpy(b, a, sizeof(b));
注意如用
sizeof(a)
,會(huì)造成
b
的內(nèi)存地址溢出。
Strcpy??
就只能拷貝字符串了,它遇到
'\0'
就結(jié)束拷貝。
例:
char a[100],b[50];strcpy(a,b);
如用
strcpy(b,a)
,要注意
a
中的字符串長(zhǎng)度(第一個(gè)
‘\0’
之前)是否超過(guò)
50
位,如超過(guò),則會(huì)造成
b
的內(nèi)存地址溢出。
str
也可以用用個(gè)參數(shù)的
strncpy(a,b,n)
========================================================
memset
主要應(yīng)用是初始化某個(gè)內(nèi)存空間。
memcpy
是用于
copy
源空間的數(shù)據(jù)到目的空間中。
strcpy
用于字符串
copy,
遇到
‘\0’
,將結(jié)束。
如果你理解了這些,你應(yīng)該知道他們的區(qū)別:例如你初始化某塊空間的時(shí)候,用到
memcpy
,那么應(yīng)該怎么寫(xiě),是不是顯得很笨。
? int ?m[100] ->memset((void*)m,0x00,sizeof(int)*100);//Ok
!
…memcpy((void*)m,"\0\0\0\0....",sizeof(int)*100);//it’s wrong.
來(lái)自CSDN的問(wèn)題
舉個(gè)例子 ======================= Name *name1=new Name[4]; Name *name2=new Name(); 假設(shè)Name類(lèi)有一方法void show(); ====================== 我一直以為由于都是由new 構(gòu)成的,所以,第一個(gè)name 和第二個(gè)name都是指針。今天剛好用第一個(gè)類(lèi)對(duì)象的方法:name1[0]->show(); 編譯器就報(bào)錯(cuò),當(dāng)我換成name1[0].show();時(shí)候,就能正確運(yùn)行了 想請(qǐng)問(wèn)下大家,既然動(dòng)態(tài)內(nèi)存是由new分配的,那name1應(yīng)該也是指針啊,因?yàn)閚ame1前有個(gè)*(即*name1),并且又是又new分配空間的。但是它調(diào)用方法時(shí)候卻又只是表現(xiàn)出只是個(gè)Name[]的數(shù)組元素。 有朋友能告訴下我到底什么樣的new 才算真正的動(dòng)態(tài)內(nèi)存分配,才算指針嗎??? 謝謝!!!
以下為解答內(nèi)容,各段為一個(gè)解答。
name1是數(shù)組指針,name1[0]就是數(shù)組中的值了.
你可以直接用name1->來(lái)調(diào)用. name1就是指針,它和name2并沒(méi)有什么不同,同樣你也可以用name2[0].來(lái)調(diào)用函數(shù).
Name[0]指的是數(shù)組中的第一個(gè)元素,不是個(gè)指針~~~~~~~ 在定義Name *name1=new Name[4]時(shí)name1確實(shí)是個(gè)指針,他指向了數(shù)組Name[] 而用name1->show()應(yīng)該是正確的,這樣的話(huà)就相當(dāng)于將函數(shù)show的首地址給了name1, Name *name2=new Name();表示開(kāi)辟了一個(gè)函數(shù)Name的內(nèi)存地址,name2表示了這個(gè)函數(shù)的首地址
我一直以為由于都是由new 構(gòu)成的,所以,第一個(gè)name 和第二個(gè)name都是指針。 -------------------- 正是如此! 都是指針,但是,name1[0]就是值了 ... 同樣,name2[0]也是一個(gè)值,樓主自己試試就知道了 ..
Name *name2=new Name(); //首先構(gòu)造Name()默認(rèn)構(gòu)造函數(shù)對(duì)象然后new出對(duì)象拷貝構(gòu)造出來(lái) Name *name2=new Name[3]; //是先分配空間然后構(gòu)造對(duì)象
Name1[0]是個(gè)對(duì)象(如果你拷貝了其他對(duì)象給他,當(dāng)然你是要拷給他才能用) Name1,Name2都是指針
和 int* p1 = new int[4]; int* p2 = new int; 一樣
指針是這樣用滴~~~ for(int i = 0;i < 4; i++) { (name1+i)->show(); }
name2 是構(gòu)造單個(gè)對(duì)象指針 name1是構(gòu)造四個(gè)對(duì)象的指針。具體到每一個(gè)對(duì)象就不是指針,而是數(shù)組
//#include class A { public: int a; int& get(){return a;}; void set(int i){ a=i;}; A() { a=1; }; }; int main() { // A* a1=new A(); A* a2=new A(); A* pA[2]={a1,a2}; int b=pA[0]->get(); // int pI[2]={1,2}; int sum=pI[1]+pI[2]; // A* pB=new A[2]; pB[1].set(1); int x=pB[1].a; return 0;
}
是指針,但是是數(shù)組的指針 比如這樣 name *p = new name[4]; p->show()相當(dāng)于p[0].show(); 通俗的說(shuō),你在定義的時(shí)候的那個(gè)name*中的*號(hào)指的是對(duì)象數(shù)組,并不是對(duì)象指針
name1[0]->show();里的name1[0]改成name1就OK了。樓主可以補(bǔ)一補(bǔ)數(shù)組的有關(guān)知識(shí)。
======================================================== copy了這篇文章,其實(shí)我只想說(shuō)下我的看法。 Name *p=new Name[4]; p->show();????? //正確 p[0].show();??? //正確 第一個(gè)可以這樣理解:指針P指向數(shù)組首地址,其實(shí)就是P指向Name[4]數(shù)組中第一個(gè)元素的地址,所以,如果使用p->show(),則意思其實(shí)就是讓數(shù)組中第一個(gè)元素,即第一個(gè)對(duì)象name調(diào)用自身show(),再說(shuō)白點(diǎn),就是name.show(); 第2個(gè)可以這樣理解:p[0]可以理解成P指向數(shù)組中第[0]個(gè)元素,所以就有了p[0],所以更會(huì)有了p[0].show();
C++內(nèi)存分配有兩種:靜態(tài)分配和動(dòng)態(tài)分配。 舉個(gè)簡(jiǎn)單的例子如下 int a=1024; 對(duì)象a的內(nèi)存空間就是靜態(tài)分配的,是在編譯器對(duì)程序進(jìn)行編譯時(shí)分配的,當(dāng)然對(duì)它空間的回收也是編譯器自動(dòng)完成的,開(kāi)發(fā)者只需要知道這個(gè)事實(shí)就好,不需要我們顯示的回收。
int *p=new int(1024); 先來(lái)說(shuō)下這句程序的意思:現(xiàn)在分配一個(gè)新的空間給一個(gè)沒(méi)有名字的Int型對(duì)象,并且為這個(gè)空間賦予初始化數(shù)值為1024。由于該Int型對(duì)象沒(méi)有名字,所以如果需要訪(fǎng)問(wèn)它的話(huà),就需要使用指針來(lái)指向該對(duì)象所在的內(nèi)存地址。注意,new int(1024)這個(gè)表達(dá)式返回的是該沒(méi)有名字的對(duì)象的內(nèi)存地址。
int *p=new int[1024]; 這個(gè)和上面的就有點(diǎn)不一樣了。可以看的出,這個(gè)是動(dòng)態(tài)分配數(shù)組,這個(gè)P叫數(shù)組指針。意思是什么呢:現(xiàn)在分配新的空間給數(shù)組里面的1024個(gè)元素,但是這1024個(gè)元素我們沒(méi)有辦法顯式的為它們分配初始化數(shù)值。并且這個(gè)指針只指向這個(gè)數(shù)組第一個(gè)元素的地址。如果想要訪(fǎng)問(wèn)其他數(shù)組元素,可以用*p++來(lái)實(shí)現(xiàn)。
既然上面兩個(gè)new 都是動(dòng)態(tài)分配的,那么自然需要手動(dòng)刪除所分配的空間了。 第一個(gè)是 delete p; 第二個(gè)是 delete[] p;
其實(shí)這個(gè)問(wèn)題我已經(jīng)想過(guò)很多時(shí)候了,但是,目前的結(jié)果仍然是:寫(xiě)程序容易,做人太累,且太難。所以,我更愿意我成為一個(gè)象傳說(shuō)中的那種頭發(fā)蓬松到另人發(fā)指仍然去參加全球C++研討會(huì)的程序員。
可能是我眼拙,普遍受歡迎的C++ 編程思想(II)我居然看著覺(jué)得很普通,寫(xiě)的思路是有點(diǎn)新鮮,但是所敘述的內(nèi)容卻有點(diǎn)泛泛而談,讓人不能完全過(guò)癮的感覺(jué)。有的文字居然還不通,讓人看了覺(jué)得有點(diǎn)莫名其妙。這可能就是大家普遍認(rèn)為的中文版不好的地方吧。 于是轉(zhuǎn)向去看C++ Primer(III)這本大部頭,感覺(jué)寫(xiě)的很不錯(cuò),雖然提前講解了OOP方面的內(nèi)容,或許會(huì)讓很多新手覺(jué)得一頭霧水,但是確實(shí)是講的都是精華的東西(聽(tīng)說(shuō)有些人因?yàn)榭戳薈++ Primer后居然投奔JAVA去了,因?yàn)榇蠖嘤X(jué)得自己連Primer這樣的書(shū)都看的不懂 )。個(gè)人感覺(jué)錢(qián)能老師的C++程序設(shè)計(jì)(II)寫(xiě)的so good,雖然有些方面沒(méi)有編程思想和Primer寫(xiě)的詳細(xì),甚至沒(méi)有涉及,但是確實(shí)為一本入門(mén)級(jí)好書(shū)。還有一本就是SAMS的21天學(xué)通C++(V),可以說(shuō)是對(duì)錢(qián)能老師書(shū)內(nèi)容的相對(duì)部分的補(bǔ)充,大家可以去看下 ?:P?? 希望自己能努力看完網(wǎng)絡(luò)上提到的很多經(jīng)典書(shū)籍,提高自己在C++思想方面的認(rèn)識(shí),早日進(jìn)入C++中級(jí)者行列(雖然本人現(xiàn)在還是新手 )。 +U!
|
|