一、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<fstream.h>
               
                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);