一、const char* 和 char* const
1、const char*
const char* 类型是指向常量的指针。 注意:const char* 等同于 char const *;
这样的指针不能修改指向的内存中的内容。但可用修改其所指向的内存地址。
char ch[5]="lisi";
const char* pStr=ch;
这里定义的字符数组元数个数为5,而不是4!因为C语言中,对于常量字符串来说,
它的最后都需要防止一个"\0"字符表示字符数组的结束,因此这里的字符数组元
素个数应该为5.
*pStr='w'; 错误:不能对指针的内容进行修改。
pStr="wangwu"; 正确:但是对指针可用修改。
2、char* const
char* const类型定义的是一个指针常量。
char ch[5]="lisi";
char* const pStr=ch; 注意:对于指针常量,必须在其定义的同时赋值。
指针常量表示指针本身是常量。因此,对于pStr来说,其值是一个指针常量,是不
能够修改的,但它所指向的内容可以修改。
pStr="zhangsan"; 错误:指针本身不能修改,这个操作相当于把字符
串"zhangsan"的首地址给pStr。
*pStr='W'; 正确:指针指向的内容是可以修改的。
知识点:const char* 类型的指针(指向常量的指针)其所指向的内容是常量,是不可以修改的,
但其指针值是可以修改的。但对于char* const 类型的指针(常量指针)来说,它的地
址是一个常量,也就是说,它的指针值是常量,不可以修改,但其指向的内容是可以
修改的。
二、C语言对文件操作的支持
1、文件的打开
FILE *fopen(const char *filename,const char *mode);
参数: filename:指向一个文件名字符串的常量指针类型,表明将要打开的文件。
mode: 指定文件打开的模式,该参数的取值如下:
r: 为读取而打开,如果文件不存在或不能找到,函数调用失败
w: 为写入操作打开一个空文件。如果给定的文件已经存在,
那么它的内容将被清空。
a: 为写入操作打开文件。如果文件已经存在,那么在该文件
尾部添加新数据,在写入新的数据之前,不会移除文件中
已有的EOF标记;如果文件不存在,那么首先创建这个文件。
r+: 打开文件用于写入操作和读取操作,文件必须存在
w+: 为写入操作和读取操作打开一个空的文件。如果给定文件
已经存在,那么它的内容将被清空
a+: 打开文件用于读取操作和添加操作,并且添加操作在添加新
数据之前会移除该文件中已有的EOF标记,然后当写入操作完
成之后在恢复EOF标记。如果文件不存在,首先创建这个文件。
2、文件的写入
size_t fwrite(const void *buffer,size_t size, size_t count,FILE *stream);
参数:buffer: 指向将要被写入文件的数据。
size: 以字节为单位的项的大小。类型是size_t,实际上就是
unsigned integer类型。
count: 将要被写入的项的最大数目。
例如:定义一个×××数组,就可以将项的大小(size)设置为4个字
节,因为整型占据4个字节。
如果该整型数组中有5个元素,就可以将count设置为5.
stream: 指向FILE类型的指针,该指针可以通过fopen函数获取到。
3、文件的关闭
fclose(pFile); pFile:是要关闭的文件。
4、fflush函数
该函数每次可以把内存缓冲区中的数据写入磁盘文件。
5、文件指针定位
int fseek(FILE *stream,long offset, int origin);
参数:stream: 指向FILE结构体指针。
offset: 设定偏移量。
origin: 指定文件指针的起始位置。该参数的取值如下:
SEEK_CUR: 从文件指针当前位置开始。
SEEK_END: 从文件的结尾处开始。
SEEK_SET: 从文件的开始处开始。
如果希望将文件指针移动到文件的开始位置处,就应该将fseek函数的origin
参数设置为SEEK_SET,并将offset参数设置为0.
6、文件的读取
size_t fread(void *buffer,size_t size,size_t count,FILE *stream);
参数:buffer: 指向用来存放数据的缓冲区的指针。
size: 以字节为单位的项的大小。类型是size_t,实际上就是
unsigned integer类型。
count: 将要被读入的项的最大数目。
例如:定义一个×××数组,就可以将项的大小(size)设
置为4个字节,因为整型占据4个字节。
如果该整型数组中有5个元素,就可以将count设置为5.
stream: 指向FILE类型的指针,该指针可以通过fopen函数获取到。
解决字符串结尾符号"\0": 在写入文件的时候多写一个字节"\0";
或者要和利用memset函数将缓冲区的数据都设置为0.
FILE *pFile=fopen("1.txt","r");
char ch[100];
memset(ch,0,100);
fread(ch,1,100,pFile);
fclose(pFile);
有时在读取文件时,并不知道文件的大小,利用ftell函数来得到文件的长度。
ftell函数将返回文件指针当前的位置。因此,可以先用fseek函数将文件指针
移动到文件的结尾处,然后用ftell函数就可以得到文件指针当前的位置,也就是
文件的长度。
FILE *pFile=fopen("1.txt","r");
char *pBuf;
fseek(pFile,0,SEEK_END);
int len=ftell(pFile);
pBuf=new char[len+1];
rewind(pFile); 将文件指针重新放回文件的开头,
同样可以用fseek函数来实现。
fread(pBuf,1,len,pFile);
pBuf[len]=0;
fclose(pFile);
注意:在读取文件数据时,如果是字符数据,通常在定义用来保持该数据的
字符数组时,在字符数据个数的基础上,多分配一个字节,以存放表示
字符串结尾的字符:"\0";
在读取文件内容时,应正确的设置文件指针的位置。
7、二进制文件和文本文件
8、文本方式和二进制方式
当按照文本方式向文件中写入数据时,一旦遇到"换行"字符(ASCII码为10),
则会转换为"回车-换行"(ASCII码分别为13、10)在读取文件时,一旦遇到"回车-换行
"的组合(连续的ASCII码为13、10),则会转换为换行字符(ASCII为10).
当按照二进制方式向文件中写入数据时,则会将数据在内存中的存储形式原样输出
到文件中。
写入和读取文件时要保持一致。如果采用文本方式写入,应采用文本方式读取;
如果采用二进制方式写入数据,在读取时也应采用二进制方式。
不管文本文件,还是二进制文件,如果统一采用二进制方式进行写入和读取,
则是不会出错的。对于数字字符来说,它们的ASCII码大于等于48,小于等于57,
在此范围之内,就是数字字符。
三、C++对文件操作的支持
在C++中,向文件中写入数据可以使用ofstream类来实现,其构造函数为:
ofstream(const char* szName,int nMode=ios::out,int nProt=filebuf::openprot);
参数: szName: 指定将要打开的文件名。
nMode: 指定文件打开的模式,其取值如下:
ios::app: 函数将执行一个定位操作,将文件指针移动到文件的结尾。
当向文件写入新数据时,将总是添加到文件的末尾处,
即使已经用ostream::seekp函数移动了文件指针的位置。
ios::ate: 函数将执行一个定位操作,将文件指针移动到文件的结尾。
当向文件写入第一个新的字节数据时,将在文件的末尾处添加。
但随后写入的其他字节的数据,被将写入到当前位置。
ios::in: 如果指定了此模式,则原始文件(如果存在的话)将不会被截断
ios::out: 打开文件,用于输出(暗指用于所有的ofstream对象)
ios::trunc: 如果文件已经存在,则它的内容将被清空,如果指定了
ios::out模式,并且没有指定 ios::app,ios::ste
和ios::in模式,则就隐含地指定了此模式
ios::nocreate: 如果文件不存在,则函数失败
ios::noreplace: 如果文件已经存在,则函数失败。
ios::binary: 以二进制方式打开文件(默认是文本方式)
nProt: 指定文件包含规格说明,取值如下:
filebuf::sh_compat: 兼容共享模式
filebuf::sh_none: 排他独占模式,不共享
filebuf::sh_read: 允许读共享
filebuf::sh_write: 允许写共享
1、ofstream写
#include
ofstream ofs("4.txt");
ofs.write("123",strlen("123"));
ofs.close();
2、ifstream读
ifstream ifs("4.txt");
char ch[4];
memset(ch,0,4);
ifs.read(ch,4);
ifs.close();
四、Win32 API对文件操作的支持
1、文件的创建和打开
HANDLE CreateFile(
LPCTSTR lpFileName, 指定用于创建或打开的对象的名称。
DWORD dwDesiredAccess, 指定对对象的访问方式,应用程序
可以的得到读访问,写访问,读写访
问或设备访问等类型。
DWORD dwShareMode, 指定共享方式。0:不能被共享,后续
对该对象进行打开操作将会失败。
直到关闭句柄为止。
LPSECURITY_ATTRIBUTES lpSecurityAttributes, 用来确定返回的句柄是否能够被子
进程所继承。
DWORD dwCreationDisposition, 指定任何创建文件。
DWORD dwFlagsAndAttributes, 设置文件属性和标志
HANDLE hTemplateFile); 指定具有GENERIC_READ访问方式的模
板文件的句柄。
2、文件的写入
BOOL WriteFile(
HANDLE hFile, 指定要写入数据的文件的句柄。
LPCVOID lpBuffer, 指向包含将要写入文件的数据的缓冲区的指针。
DWORD nNmberOFBytesToWrite, 指明要向文件中写入的字节数。
LPDWORD lpNumberOfBytesWritten, 用来接受实际写入到文件中的字节数。
LPOVERLAPPED lpOverlapped); 指向OVERLAPPED结构的指针。
HANDLE hFile; 定义一个句柄遍历
hFile=CreateFile("5.txt",GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
创建文件
DWORD dwWrites; 接受实际写入的字节数
WriteFile(hFile,"123",strlen("123"),&dwWrites,NULL); 写入数据
Closehandle(hFile); 关闭文件句柄。
3、文件的读取
BOOL ReadFile(
HANDLE hFile, 指定要读取其数据的文件的句柄。
LPVOID lpBuffer, 指向一个缓冲区的指针,该缓冲区将接收从文件
中读取的数据。
DWORD nNumberOfBytesToRead, 指定从文件读取的字节数
LPDWORD lpNumberOfBytesRead, 用来接收实际读到的字节数。
LPOVERLAPPED lpOverlapped); 指向OVERLAPPED结构的指针。
HANDLE hFile;
hFile=CreateFile("5.txt",GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
打开文件
char ch[100]; 接收实际读取到的数据。
DWORD dwReads; 接收实际读取到的字节数
ReadFile(hFile,ch,100,&dwReads,NULL); 读取数据
ch[dwReads]=0; 设置字符串结束符。
CloseHandle(hFile); 关闭打开的文件对象的句柄。
五、MFC对文件操作的支持
1、文件创建
CFile(
LPCTSTR lpszFileName, 指定文件的名称。
UINT nOpenFlags); 指定文件共享和访问的方式。
2、文件的写入
CFile file("6.txt",CFile::modeCreate|CFile::modeWrite);
file.Write("123",strlen("123"));
file.Close();
3、文件的读取
CFile file("6.txt",CFile::modeRead);
char *pBuf;
DWORD dwFileLen;
dwFileLen=file.GetLength();
pBuf=new char[dwFileLen+1];
pBuf[dwFileLen]=0;
file.Read(pBuf,dwFileLen);
file.Close();
六、Win.ini文件的访问
1、Wini.ini文件的写入
BOOL WriteProfileString(
LPCTSTR lpAppName, 指向一个以0结尾的字符串指针,该字符串包含了将把字符串
复制到Wini.ini文件中的那个段名,如果段不存在,则创建。
LPCTSTR lpKeyName, 指向一个以0结尾的字符串的指针,该字符串包含了一个键的
名字。如果键在指定段中不存在,在创建这个键。如果这个参
数为NULL,则整个段,包括段中的所有项,都将被删除。
LPCTSTR lpString); 指向一个以0结尾的字符串的指针,该字符串将要被写入到
Wini.ini文件中。如果此参数为NULL,则参数lpKeyName所
指定的键将被删除。
WriteProfileString("123","admin","zhangsan");
ini文件中的体现
[123]
admin=zhangsan
2、Wini.ini文件的读取
DWORD GetProfileString(
LPCTSTR lpAppName, 指向一个空终止的字符串指针,该字符串指定含有所需键的段。
LPCTSTR lpKeyName, 指向一个空终止的字符串指针,该字符串包含了一个键的名称,
与该键相关联的字符串被获取。
LPCTSTR lpDefault, 指向一个空终止的默认字符串,如果lpKeyName所指的键不存储。
则函数将默认字符串复制到lpReturnedString所指向的缓冲区中。
LPTSTR lpReturnedString,指向一个缓冲区的指针,该缓冲区将接收获得的字符串。
DWORD nSize); 指定参数lpReturnedString所指向的缓冲区的大小,单位是字节。
CString str;
GetProfileString("123","admin","lisi",str.GetBuffer(100),100);
七、注册表的编程
1、创建键
LONG RegCreateKey(
HKEY hKey, 指向当前打开表项的句柄。
LPCTSTR lpSubKey, 指向一个空终止的字符串指针,指示这个函数打开或创
建的表项的名称。这个表项必须是有hKey参数所标识的
项的子项。
PHKEY phkResult); 这是一个返回值,指向一个变量的指针,用来接收创建
或打开的表项的句柄。
2、打开键
LONG RegOpenKey(
HKEY hKey, 同RegCreateKey函数的hKey参数。
LPCTSTR lpSubKey, 同RegCreateKey函数的lpSubKey参数。
PHKEY phkResult); 指向一个变量的指针,该变量保持此函数所打开的注
册表项的句柄。
3、写入注册表
LONG RegSetValue(
HKEY hKey, 同RegCreateKey函数的hKey参数。
LPCTSTR lpSubKey, 同RegCreateKey函数的lpSubKey参数。
DWORD dwType, 指示将被存储的信息类型。该参数必须是REG_SZ类型,
实际上就是字符串类型。
LPCTSTR lpData, 指向一个空终止的字符串,该字符串中包含了要为指定项的
默认值设置的数据。
DWORD cbData); 指示lpData参数所指向的字符串的大小,单位是字节,但不
包含字符串最后的空终止字符。
另外,如果想要设置注册表项下不是默认值,即有名称值的数据和类型时,可以调用
RegSetValueEx函数,该函数将在注册表项下设置指定值的数据和类型。
4、从注册表中读数据。
LONG RegQueryValue(
HKEY hKey, 同RegCreateKey函数的hKey参数。
LPCTSTR lpSubKey, 同RegCreateKey函数的lpSubKey参数。
LpTSTR lpValue, 指向一个缓存区,用来获得与指定子项默认值
相关的一个字符串。
PLONG lpcbValue); 指向一个变量,指定用此参数指定的buffer的大小。
同样,如果想要读取注册表项下不是默认值,即有名称值的数据和类型时,可以调用
RegQueryValueEx函数。该函数将读取注册表项下指定值的数据和类型。
5、关闭注册表
RegCloseKey(
HKEY hKey) 同RegCreateKey函数的hKey参数。
6、操作注册表的实例:
HKEY hKey;
RegCreateKey(HKEY_LOCAL_MACHINE,"Software\\123\\admin",&hKey);
RegSetValue(hKey,NULL,REG_SZ,"zhangsan",strlen("zhangsan")); 增加默认键值
LONG lValue;
读取默认键值的数据长度。
RegQueryValue(HKEY_LOCAL_MACHINE,"Software\\123\\admin",NULL,&lValue);
分配指定长度的内存。
char *pBuf=new char[lValue];
读取默认键值的数据。
RegQueryValue(HKEY_LOCAL_MACHINE,"Software\\123\\admin",pBuf,&lValue);
DWORD dwAge=30;
增加指定键值。
RegSetValueEx(hKey,"age",0,REG_DWORD,(CONST BYTE*)&dwAge,4);
DWORD dwType;
DWORD dwValue;
DWORD dwAge;
读取指定键值的数据。
RegQueryValueEx(hKey,"age",0,&dwType,(LPBYTE)&dwAge,&dwValue);
CString str;
str.Format("age=%d",dwAge);
RegCloseKey(hKey);