1. C文件操作
1)打開一個(gè)文件
FILE* fp; //定義文件指針:
fp=fopen("文件名","文件使用方式");
文件使用方式:
"r"(只讀) 為輸入打開一個(gè)文本文件
"w"(只寫) 為輸出打開一個(gè)文本文件
"a"(追加) 向文本文件尾追加數(shù)據(jù)
"rb"(只讀) 為輸入打開一個(gè)二進(jìn)制文件
"wb"(只寫) 為輸出打開一個(gè)二進(jìn)制文件
"a" (追加) 向二進(jìn)制文件尾追加數(shù)據(jù)
"r+"(讀寫) 為讀/寫打開一個(gè)文本文件
"w+"(讀寫) 為讀/寫建立一個(gè)新的文本文件
"a+"(讀寫) 為讀/寫打開一個(gè)文本文件(可以添加)
"rb+"(讀寫) 為讀寫打開一個(gè)二進(jìn)制文件
"wb+"(讀寫) 為讀寫打開一個(gè)二進(jìn)制文件
"ab+"(讀寫) 為讀寫打開一個(gè)二進(jìn)制文件(可以添加)
2)讀/寫二進(jìn)制數(shù)據(jù)
fread(buffer,size,count,fp);
fwrite(buffer,size,count,fp);
buffer是一個(gè)指針,在freed中是讀入數(shù)據(jù)的存放地址;在fwrite中是要輸出數(shù)據(jù)的地址,以
上地址是起始地址;
size是要讀寫的字節(jié)數(shù);
count是要進(jìn)行讀寫多個(gè)人size字節(jié)的數(shù)據(jù)項(xiàng)
fp是文件型指針
3)讀/寫ASCII字符串
fprintf(文件指針,格式字符串,輸出列表);
fscanf (文件指針,格式字符串,輸出列表);
4)其它讀/寫例程
ch=fgetc(fp); //讀寫一個(gè)字符
fputc(ch, fp);
putw(i,fp); //讀寫一個(gè)整數(shù)
i=getw(fp);
fgets(str,n,fp); //讀寫一個(gè)字符串,返回值為str的首地址
fputs(str,fp);
5)文件檢索
fseek (文件類型指針,位移量,起始點(diǎn));
“起始點(diǎn)”用0 1 和 2代替,0代表“文件開始”,1為“當(dāng)前位置”,2為“文件末尾”;
“位移量”是以“起始點(diǎn)”為基點(diǎn),向前移動(dòng)的字節(jié)數(shù);
此函數(shù)主要用于二進(jìn)制文件
rewind (fp); //文件指針返回文件開頭
i=ftell(fp); //返回文件指針當(dāng)前位置
6)文件關(guān)閉:
fclose(fp);
更深入的討論見任何一本C語言教材
2. C++文件流操作
0)包含的頭文件
#include <fstream>
using namespace std;
1)C++中的三個(gè)文件流
ofstream ofs("文件名", 打開方式);
ifstream ifs("文件名", 打開方式);
fstream fs("文件名",輸入打開方式 | 輸出打開方式);
三種文件流分別用于寫文件、讀文件、讀寫文件
三種文件流都可先定義,再打開文件,以fstream為例
fstream fs;
fs.open("文件名", 輸入打開方式 | 輸出打開方式);
其中“打開方式”可以不給出。
若不給出,對(duì)于oftream默認(rèn)為ios::out,iftream默認(rèn)為ios::in
2)打開方式
ios::out 輸出數(shù)據(jù)覆蓋現(xiàn)有文件
ios::app 輸出數(shù)據(jù)填加之現(xiàn)有文件末尾
ios::ate 打開文件并移動(dòng)文件指針至末尾
ios::in 打開文件以輸入
ios::trunc 輸出文件中現(xiàn)有內(nèi)容(ios::out的默認(rèn)操作)
ios::binary 二進(jìn)制打開供讀寫
3)寫ASCII文件
利用<<將數(shù)據(jù)插入ofstream或fstream流中
例:
int account=10;
char name[]="pzhg";
double balance=100.23;
ofstream ofs("account.dat",ios::out);
if (!ofs)
{
cerr<<"Failed Opening a File";
exit(1);
}
ofs<<account<<" "<<name<<" "<<balance<<endl;
4)讀ASCII文件
利用>>將數(shù)據(jù)從ifstream或ftream流中讀出
例:
int account;
char name[30];
double balance;
ifstream ifs("account.dat",ios::in);
if (!ifs)
{
cerr<<"Failed Opening a File";
exit(1);
}
while (ifs>>account>>name>>balance)
{
cout<<account<<" "<<name<<" "<<balance<<endl;
}
只要不讀到文件末尾ifs>>Variable就返回true
5)檢索文件
以下兩個(gè)方法
ofstream::seekp(位置,起始點(diǎn));
ifstream::seekg(位置,起始點(diǎn));
起始點(diǎn)可以有:
ios::beg 相對(duì)于流的開頭(默認(rèn))
ios::cur 相對(duì)于當(dāng)前位置
ios::end 相對(duì)于流的結(jié)尾
位置參數(shù)為相對(duì)于起始點(diǎn)的偏移量
6)讀/寫二進(jìn)制文件
ifstream::read(reinterpret_cast<char*>(&要讀入的變量),sizeof(變量類型));
ofstream::write(reinterpret_cast<const char*>(&要寫入的變量),sizeof(變量類型))
例如:
int i;
ifstream ifs("data.dat");
ifs.read(reinterpret_cast<char*>(&i),sizeof(int));
ofstream ofs("data.dat");
ofs.write(reinterpret_cast<const char*>(&i),sizeof(int));
7)文件關(guān)閉
fs.close();
3. 關(guān)于i+=++i+++i+++i之類的問題
這種++--多次出現(xiàn)或者是同一個(gè)變量在左右值同時(shí)出現(xiàn)還有++--……等情況下,表達(dá)式值
不定,與實(shí)現(xiàn)有關(guān)。誰有興趣可以自己研究,本版不討論
4. <iostream>與<iostream.h>
前者是C++標(biāo)準(zhǔn)的用法,后者不符合標(biāo)準(zhǔn),但為兼容老代碼仍然暫時(shí)存在。
注意,使用
#include <iostream>
以及幾乎所有的C++標(biāo)準(zhǔn)庫后,為正常使用各種常量與變量,須使用命名空間
using namespace std;
或者在每一個(gè)標(biāo)準(zhǔn)常/變量前加注命名空間名稱,如
std::cout<<"Bla Bla.."<<std::endl;
注意:所謂“前者是后者的再包裝”等說法是沒有道理的
5. 指針與數(shù)組的區(qū)別
指針與數(shù)組容易混淆。例如一下這里例子:
int a[10];
int* p;
分別定義了一個(gè)數(shù)組與一個(gè)指針。兩者的混淆主要發(fā)生在數(shù)組向指針賦值時(shí):
p=a;
與函數(shù)調(diào)用時(shí):
void foo(int* p);
foo(a);
其實(shí)這些情況下,數(shù)組名都退化成了數(shù)組的首地址。
指針是一個(gè)占地四個(gè)字節(jié)(目前主流32位機(jī))的變量,里面存有地址。
數(shù)組是一片連續(xù)的儲(chǔ)存空間,以順序結(jié)構(gòu)儲(chǔ)存數(shù)據(jù)。
單獨(dú)引述數(shù)組名的時(shí)候,數(shù)組明會(huì)退化為這片連續(xù)空間的首地址。
p=a以后,這個(gè)首地址存到了指針中,所以我們說指針指向了一個(gè)數(shù)組。
可以看這個(gè)圖:
__ __ __ __ a ___ ___ ___ ___ ___ _
p|__|__|__|__| ---> |___|___|___|___|___|_……
a是數(shù)組名,不存在一個(gè)單獨(dú)的“指針常量”a。
p是一個(gè)指針變量,有自己的儲(chǔ)存空間,它可以指向一個(gè)數(shù)組。
但絕不能說“數(shù)組名是指針常量”,數(shù)組就是數(shù)組,它不是指針,它可以退化為數(shù)組的首
不信可以看看,在目前的大部分32位機(jī)中(32bit=4字節(jié)),sizepf(p)與sizeof(a),sizeof(p)==4,sizeof(a)==10*sizeof(int)。
6. char*與char[]
有時(shí)可以看到兩種字符串的定義:
char* strp="pzhg is zt";
char stra[]="pzhg is zt";
兩者區(qū)別有二:
1)參考上一條,兩者一個(gè)是字符指針,指向一個(gè)字符串常量;一個(gè)是字符數(shù)組
2)由于第一種寫法指向了一個(gè)常量,所以類似于strp[0]='a'的賦值操作就是非法的
實(shí)際上,在最新的標(biāo)準(zhǔn)中,第一種寫法是不符合規(guī)范的
但為了兼容老代碼這種寫法仍暫時(shí)可以使用。規(guī)范的寫法是:
const char* strp="pzhg is zt";
const標(biāo)志了指針指向的內(nèi)容不能被修改。
7. 隨機(jī)數(shù)的使用
計(jì)算機(jī)中產(chǎn)生不了真正的隨機(jī)數(shù),只能產(chǎn)生偽隨機(jī)數(shù)
1)srand()與rand()
在C/C++中,偽隨機(jī)數(shù)由以下兩個(gè)函數(shù)配合生成:
srand(unsigned); //初始化隨機(jī)種子
rand(void); //生成0~RAND_MAX的偽隨機(jī)數(shù),RAND_MAX宏在stdlib中定義
要正常使用隨機(jī)數(shù),應(yīng)包含兩個(gè)頭文件
C中:
#include <stdlib.h>
#include <time.h>
C++中:
#include <cstdlib>
#include <ctime>
using namespace std;
2)使用隨機(jī)數(shù)
使用很簡(jiǎn)單,用srand()初始化隨機(jī)數(shù)種子,然后用rand()返回隨機(jī)數(shù)。
srand()一般使用時(shí)間來初始化隨機(jī)種子,格式為srand((unsigned)time(NULL));
rand()返回0到RAND_MAX的隨機(jī)整數(shù)。若要使用0到N的隨機(jī)數(shù),可以使用rand()%N
3)一些常見的錯(cuò)誤
a.多次初始化種子
隨機(jī)數(shù)種子在第一次調(diào)用rand()前初始化一次即可,以后不用初始化。
b.使用類似 rand()*100/RAND_MAX 的寫法
由于偽隨機(jī)數(shù)生成算法,這樣產(chǎn)生的第一個(gè)偽隨機(jī)數(shù)與時(shí)間成線性關(guān)系。
要達(dá)到真正的隨機(jī)效果,應(yīng)使用rand()%100
8. EOF字符
DOS下是ctrl+z,Unix下是ctrl+d
11.標(biāo)準(zhǔn)C/C++的main函數(shù)聲明
最新的C/C++標(biāo)準(zhǔn)都約定了main函數(shù)的聲明方式,可惜的是,市面各種書籍與教師
的課堂教授,由于歷史原因,沒有完全遵循這些約定
1)標(biāo)準(zhǔn)C程序
標(biāo)準(zhǔn)C程序main函數(shù)聲明如下:
int main(void)
{
//...
return 0;
}
注意,標(biāo)準(zhǔn)建議main需顯式聲明為int型。C99以前,由于函數(shù)不指定返回類型默認(rèn)為
int型,類似main()的聲明也是接受的,K&R也是這么寫的。但是在C99中必須加上int。
標(biāo)準(zhǔn)中約定main可以有以下兩種聲明方式:
int main(void)
int main(int argc, char* argv[]) //char** argv亦可
其他聲明方式都是標(biāo)準(zhǔn)所不允許的,當(dāng)然也許實(shí)現(xiàn)出于兼容性仍會(huì)支持
return 0不可少,表示程序正常返回。
2)標(biāo)準(zhǔn)C++程序
標(biāo)準(zhǔn)C++的main函數(shù)與C大致類似
int main()
{
//...
return 0;
}
C++中約定的標(biāo)準(zhǔn)main的聲明函數(shù)同樣有兩種:
int main() //對(duì)應(yīng)于C99的int main(void)
int main(int argc, char* argv[]) //同C99,也可為char** argv
其他聲明方式也都是不允許的。return 0也必不可少。
3)關(guān)于void main()
不論C還是C++,不論過去還是現(xiàn)在,main前面加void都是絕對(duì)不被允許的。C++
之父 Bjarne Stroustrup 在他的主頁上的 FAQ 中明確地寫著 The definition void
main()is not and never has been C++, nor has it even been C.
部分編譯器對(duì)void main采取放行態(tài)度是兼容性的考慮,絕不是因?yàn)槠湔_。[quote][/quote]