vc读写配置文件方法
- 格式:doc
- 大小:35.50 KB
- 文档页数:5
C语⾔读取写⼊ini配置⽂件的⽅法实现⽬录⼀、了解什么是INI⽂件?⼆、INI⽂件的格式三、解析上述⽂件四、测试如下⼀、了解什么是INI⽂件?ini ⽂件是Initialization File的缩写,即初始化⽂件,这是⽤来配置应⽤软件以实现不同⽤户的要求。
⼆、INI⽂件的格式INI⽂件由节、键、值组成。
⼀个简单的的INI⽂件例⼦如下:[Setting]INIT_FLAG=0;VOLUME=1;LANGUAGE=1;如上例⼦,[Setting]就是节,=号左边的值是键,=号右边的是值。
三、解析上述⽂件/*ini.h*/#ifndef INI_H#define INI_H#include <stdio.h>#include <string.h>int GetIniKeyString(char *title,char *key,char *filename,char *buf);int PutIniKeyString(char *title,char *key,char *val,char *filename);#endif /*INI_H*//*ini.c*/#include <stdio.h>#include <string.h>/** 函数名: GetIniKeyString* ⼊⼝参数: title* 配置⽂件中⼀组数据的标识* key* 这组数据中要读出的值的标识* filename* 要读取的⽂件路径* 返回值:找到需要查的值则返回正确结果 0* 否则返回-1*/int GetIniKeyString(char *title,char *key,char *filename,char *buf){FILE *fp;int flag = 0;char sTitle[64], *wTmp;char sLine[1024];sprintf(sTitle, "[%s]", title);if(NULL == (fp = fopen(filename, "r"))) {perror("fopen");return -1;}while (NULL != fgets(sLine, 1024, fp)) {// 这是注释⾏if (0 == strncmp("//", sLine, 2)) continue;if ('#' == sLine[0]) continue;wTmp = strchr(sLine, '=');if ((NULL != wTmp) && (1 == flag)) {if (0 == strncmp(key, sLine, strlen(key))) { // 长度依⽂件读取的为准sLine[strlen(sLine) - 1] = '\0';fclose(fp);while(*(wTmp + 1) == ' '){wTmp++;}strcpy(buf,wTmp + 1);return 0;}} else {if (0 == strncmp(sTitle, sLine, strlen(sTitle))) { // 长度依⽂件读取的为准flag = 1; // 找到标题位置}}}fclose(fp);return -1;}/** 函数名: PutIniKeyString* ⼊⼝参数: title* 配置⽂件中⼀组数据的标识* key* 这组数据中要读出的值的标识* val* 更改后的值* filename* 要读取的⽂件路径* 返回值:成功返回 0* 否则返回 -1*/int PutIniKeyString(char *title,char *key,char *val,char *filename){FILE *fpr, *fpw;int flag = 0;char sLine[1024], sTitle[32], *wTmp;sprintf(sTitle, "[%s]", title);if (NULL == (fpr = fopen(filename, "r")))return -1;// 读取原⽂件sprintf(sLine, "%s.tmp", filename);if (NULL == (fpw = fopen(sLine, "w")))return -1;// 写⼊临时⽂件while (NULL != fgets(sLine, 1024, fpr)) {if (2 != flag) { // 如果找到要修改的那⼀⾏,则不会执⾏内部的操作wTmp = strchr(sLine, '=');if ((NULL != wTmp) && (1 == flag)) {if (0 == strncmp(key, sLine, strlen(key))) { // 长度依⽂件读取的为准flag = 2;// 更改值,⽅便写⼊⽂件sprintf(wTmp + 1, " %s\n", val);}} else {if (0 == strncmp(sTitle, sLine, strlen(sTitle))) { // 长度依⽂件读取的为准flag = 1; // 找到标题位置}}}fputs(sLine, fpw); // 写⼊临时⽂件}fclose(fpr);fclose(fpw);sprintf(sLine, "%s.tmp", filename);return rename(sLine, filename);// 将临时⽂件更新到原⽂件}上述两个函数是简单的解析函数,因为ini⽂件有很多种解析⽅式,根据不同的需求解析也不同所以要进⾏修改⽐如我的注释符号是 “ ;”,所以我需要修改并且根据实际功能需求也可以进⾏进⼀步的封装四、测试如下ini样本⽂件/*test.ini*/[city]beijing = hello-beijingshanghai = hello-shanghai#information[study]highschool = xxxxuniversity = yyyytest.c程序/*test.c*/#include "ini.h"#include <stdio.h>int main(int argc, char const *argv[]){char buff[100];int ret;ret = GetIniKeyString("city","beijing","./test.ini",buff);printf("ret:%d,%s\n",ret,buff);ret = GetIniKeyString("study","highschool","./test.ini",buff);printf("ret:%d,%s\n",ret,buff);ret = PutIniKeyString("study","highschool","zzzz","./test.ini");printf("put ret:%d\n",ret);ret = GetIniKeyString("study","highschool","./test.ini",buff);printf("ret:%d,%s\n",ret,buff);return 0;}结果如下:ret:0,hello-beijingret:0,xxxxput ret:0ret:0,zzzz相应的test.ini的study段highschool项变成了zzzz.这⾥还要注意,section使⽤中⽂字符可能会⽆法识别!到此这篇关于C语⾔读取写⼊ini配置⽂件的⽅法实现的⽂章就介绍到这了,更多相关C语⾔读取写⼊ini 内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。
⼤多数的应⽤程序都有需要配置的参数,配置参数的保存有多种⽅法,⽐如采⽤数据库保存、⼆进制⽂件保存、格式化的⽂本⽂件保存,各有优缺点,对于⼀般⼩的安全性要求不⾼应⽤程序,推荐采⽤格式化⽂本⽂件保存⽅式,这样可以节约编辑修改的界⾯编程,使⽤记事本程序编辑即可。
早期的windows就是采⽤的INI格式⽂本⽂件。
现在很多应⽤程序包括⼤型的软件也还在采⽤格式化⽂本⽂件保存配置参数,⽐如Bentely MicroStation GIS平台GEOGRAPHICS8.0。
本⽂给出的就是利⽤VC来读取和分析配置⽂本⽂件,这是笔者这消防监控系统远程终端软件使⽤的⽅法。
同时给出⼀个C++类来封装配置⽂本⽂件的读取分析。
下⾯是我采⽤的配置⽂件的例⼦,包含单个参数定义,表格参数定义,注释: // 协议名称: TL // ⼯程: SQ // 配置⼈: JY #DEFINE_BEGIN //以下为常量定义 //通信参数 @COM_PORT \\\\.\\COM1 //COM⼝ @COM_BAUDRATE 1200 //波特率 @COM_BITSIZE 8 //数据位 number of bits/byte, 4-8 @COM_SBIT 0 // 0,1,2 对应 1, 1.5, 2 @COM_PARITY 0 //0-4对应no,odd,even,mark,space @STATIONNO 0 //终端号 @TCPIP_SERVERIP 192.168.0.10 //服务器IP地址 @TCPIP_PORTNO 3024 //端⼝ #DEFINE_END #TABLE_BEGIN //表格 //编号识别字符串 //例⼦如下 0 Ion Detector, ALU1, L1S43 //测量台2#离⼦烟感探测器报警 1 Thermal Det, ALU1, L1S39 //值班室温感探测器报警 #TABLE_END 语法解释: // 单⾏注释 #DEFINE_BEGIN 单个参数定义的开始标记 #DEFINE_END 单个参数定义的结束标记 #TABLE_BEGIN 表格参数开始标记 #TABLE_END 表格参数结束标记 单个参数的配置: 每个参数⼀⾏:以空格、TAB制表符作为分隔,注释可选,每⾏结束后有Enter键换⾏。
VC++中对文件的写入和读取本文介绍两种方法对文件进行读取和写入操作:1、采用fstream 类;2、采用CStdioFile类。
CStdioFile继承自CFile,一个CStdioFile对象代表一个用运行时函数fopen 打开的C 运行时流式文件。
C++中的fstream类,所有的I/O都以这个“流”类为基础的,包括我们要认识的文件I/O。
stream类有两个重要的运算符:插入器(<<)和析取器(>>)。
插入器(<<)即向流输出数据,析取器(>>)即从流中输入数据。
在C++中,对文件的操作是通过stream的子类fstream(file stream)来实现的,所以,要用这种方式操作文件,就必须加入头文件fstream.h。
fstream类包括向“流”输出数据的ofstream类和从“流”中输出数据的ifstream类。
1、文件的写入往文件中写入数据的操作较为简单,这里以fstream类中往文件写入数据为例,介绍VC++中对文件的写入方法。
对于用CstdioFile 类对文件进行写入操作可参看相关资料。
下面给出采用fstream类对文件进行写入操作的代码:#include <fstream.h>ofstream of1;//创建对象of1.open("数据记录.txt",ios::out,filebuf::openprot);//打开文件int i;//定义一个整型变量float f; //定义一个单精度浮点型变量double d; //定义一个双精度浮点型变量i=123;//赋值f=3.478f; //赋值d=859.653; //赋值of1<<i<<’\t’<<f<<’\t’<<d;//写入数据of1.close();//关闭文件运行后打开“数据记录.txt”文件,内容见图1,变量i,f,d已写入文件中。
VC中的文件读写操作各种关于文件的操作在程序设计中是十分常见,如果能对其各种操作都了如指掌,就可以根据实际情况找到最佳的解决方案,从而在较短的时间内编写出高效的代码,因而熟练的掌握文件操作是十分重要的。
本文将对Visual C++中有关文件操作进行全面的介绍,并对在文件操作中经常遇到的一些疑难问题进行详细的分析。
1.文件的查找当对一个文件操作时,如果不知道该文件是否存在,就要首先进行查找。
MFC中有一个专门用来进行文件查找的类CFileFind,使用它可以方便快捷地进行文件的查找。
下面这段代码演示了这个类的最基本使用方法。
CString strFileTitle;CFileFind finder;BOOL bWorking = finder.FindFile("C:\\windows\\sysbkup\\*.cab");while(bWorking){bWorking=finder.FindNextFile();strFileTitle=finder.GetFileTitle();}2.文件的打开/保存对话框让用户选择文件进行打开和存储操作时,就要用到文件打开/保存对话框。
MFC的类CFileDialog用于实现这种功能。
使用CFileDialog声明一个对象时,第一个BOOL型参数用于指定文件的打开或保存,当为TRUE时将构造一个文件打开对话框,为FALSE时构造一个文件保存对话框。
在构造CFileDialog对象时,如果在参数中指定了OFN_ALLOWMULTISELECT风格,则在此对话框中可以进行多选操作。
此时要重点注意为此CFileDialog对象的m_ofn.lpstrFile 分配一块内存,用于存储多选操作所返回的所有文件路径名,如果不进行分配或分配的内存过小就会导致操作失败。
下面这段程序演示了文件打开对话框的使用方法。
CFileDialog mFileDlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_ALLOWMULTISELECT, "All Files (*.*)|*.*||",AfxGetMainWnd());CString str(" ",10000);mFileDlg.m_ofn.lpstrFile=str.GetBuffer(10000);str.ReleaseBuffer();POSITION mPos=mFileDlg.GetStartPosition();CString pathName(" ",128);CFileStatus status;while(mPos!=NULL){pathName=mFileDlg.GetNextPathName(mPos);CFile::GetStatus( pathName, status );}3.文件的读写文件的读写非常重要,下面将重点进行介绍。
c读取配置文件的方法在C语言中,读取配置文件是一项非常常见的任务。
配置文件通常包含了程序运行时需要的各种参数和设置,因此读取配置文件是程序启动时必须完成的任务之一。
本文将介绍如何使用C语言读取配置文件。
我们需要了解配置文件的格式。
配置文件通常是一个文本文件,其中包含了一系列的键值对。
每个键值对由一个键和一个值组成,中间用等号连接。
例如:```key1=value1key2=value2key3=value3```在C语言中,我们可以使用标准库中的fopen函数打开配置文件。
例如:```cFILE *fp = fopen("config.ini", "r");```这里我们打开了一个名为config.ini的文件,并以只读模式打开。
接下来,我们可以使用标准库中的fgets函数逐行读取配置文件。
例如:```cchar line[256];while (fgets(line, sizeof(line), fp)) {// 处理每一行}```这里我们定义了一个长度为256的字符数组line,然后使用fgets 函数逐行读取配置文件。
fgets函数的第一个参数是一个字符数组,用于存储读取到的行;第二个参数是字符数组的长度;第三个参数是文件指针,用于指定要读取的文件。
接下来,我们需要解析每一行的键值对。
我们可以使用标准库中的strtok函数将每一行按照等号分割成键和值。
例如:```cchar *key = strtok(line, "=");char *value = strtok(NULL, "=");```这里我们使用strtok函数将line按照等号分割成两个部分,分别是键和值。
strtok函数的第一个参数是要分割的字符串;第二个参数是分割符,这里是等号。
strtok函数会返回分割后的第一个部分,我们可以使用NULL作为第一个参数来获取分割后的第二个部分。
CFile和CStdioFile的文件读写使用方法(2009-08-18 10:35:01)标签:杂谈CFile//创建/打开文件CFile file;file.Open(_T("test.txt"),CFile::modeCreate|CFile::modeNoTruncate|CFile::modeRead Write);文件打开模式可组合使用,用“|”隔开,常用的有以下几种:CFile::modeCreate:以新建方式打开,如果文件不存在,新建;如果文件已存在,把该文件长度置零,即清除文件原有内容。
CFile::modeNoTruncate:以追加方式打开,如果文件存在,打开并且不将文件长度置零,如果文件不存在,会抛出异常。
一般与CFile::modeCreate一起使用,则文件不存在时,新建一个文件;存在就进行追加操作。
CFile::modeReadWrite:以读写方式打开文件。
CFile::modeRead:只读。
CFile::modeWrite:只写。
//写入数据CString strValue = "Hello World!";file.Write(strValue,strValue.GetLength());//追加数据file.SeekToEnd(); //将指针移至文件末尾进行追加file.Write(strValue,strValue.GetLength());//关闭文件file.Close();CStdioFileCStdioFile是CFile的派生类,对文件进行流式操作,对于文本文件的读写很有用处,可按行读取写入。
//写入数据CString strValue = "Hello World!";file.WriteString(strValue);//读取数据CString strRead;file.ReadString(strRead);当文件存在多行数据需要逐行读取时,可用函数BOOL CStdioFile::ReadString(CString& rString),当遇到"\n "时读取截断,如果文件未读完,返回true,否则返回false。
VC++添加菜单并读写ini文件数据1、打开VC++6.0,选择新建。
2、选择“工程”,选择“MFC AppWizard(exe)”,选择工程所建立的位置,并输入工程名。
单击“确定”。
3、在弹出的对话框中选择“基本对话框(D)”,点击“下一步”。
4、在弹出的想到对话框中取消“‘关于’对话框”(可省略该步)。
点击“完成”。
5、在弹出的对话框中直接点击“确定”。
6、在“ResourceView”标签下,在“Testresources”上单击右键,再弹出菜单中选择“插入”。
7、在弹出对话框中选择“Menu”,并点击“新建”。
8、弹出下面的对话框,选择“Menu”,并选中所要编辑的菜单,这里是“IDR_MENU”,在右边的编辑区编辑菜单。
9、双击菜单区中白色方框,弹出“菜单项目属性”对话框,在“标明”框中输入要显示的菜单项。
这里随便输入一个,说明操作方法和效果。
我们输入“文件(&W)”,括号内表示快捷键。
10、在“文件”菜单出现之后,其下面会再有一个白色框的空白区域,表示下拉菜单。
双击,出现“菜单项目属性”对话框,输入“ID”(必须)和“标明”,我们在“标明”中输入“操作ini\t(Ctrl+A)”,“操作ini”表示要显示的菜单项,“(Ctrl+A)”表示快捷键,“\t”会将所有下拉菜单的快捷键自动对齐。
11、还可以选择“分隔符”,在前面的小方框内打勾,会出现一个分隔符。
12、按照上述方法设计好菜单。
13、将所设计的菜单加入对话框。
在“TestDlg.cpp”的OnInitDialog函数中中加入下面代码:CMenu m_menu;m_menu.LoadMenu(IDR_MENU1);SetMenu(&m_menu);如下图所示:14、运行程序,看是否有误,如果无误,会出现下图所以的结果。
15、在“ResourceView”标签下,在“Dialog”上单击右键,再弹出菜单中选择“插入Dialog”。
目录目录第1章读写文件 (1)1.1 API (1)1.2 低级IO (1)1.2.1 文件序号 (1)1.2.2 文本文件与二进制文件 (1)1.3 流IO (2)1.4 Unicode (3)1.5 低级IO、流IO、API之间的关系 (3)1.6 随机读写 (3)1.7 C++IO流 (4)1.8 MFC (4)1.8.1 CFile (4)1.8.2 CStdioFile (4)1.8.3 CArchive (4)1.9 总结 (4)II第1章读写文件1.1 API使用VC++读写文件,最直接、最高效的方法就是使用 Windows API,如:使用 CreateFile 打开文件,使用 WriteFile 写文件,使用 ReadFile 读文件……Windows 平台下,所有对文件的读写操作,最终都会调用这些 API 函数。
使用 API 的效率最高,对文件读写的控制最强,缺点就是比较复杂,而且代码没有可移植性。
1.2 低级IO为了方便移植 UNIX 的C代码,VC++的C运行时库实现了一套低级IO 函数,如:_open、_write、_read……1.2.1 文件序号_open返回的是一个整数,MSDN上称其为文件句柄(file handle),这与CreateFile返回的文件句柄容易混淆。
为此,本文称_open返回的为文件序号。
VC++中,系统预先打开了三个文件,其文件序号如下表所示流文件序号说明stdin 0 标准输入设备,一般就是键盘stdout 1 标准输出设备,一般就是控制台stderr 2 标准错误输出设备,一般就是控制台也就是说,无需调用_open,可以直接调用_write(1,"abc",3);往控制台输出a bc三个字符。
1.2.2 文本文件与二进制文件读写二进制文件时,不会做任何处理,数据保持原样。
写文本文件时,V1C++会将换行符(即\n,0AH)替换为回车(即\r,0DH)和换行符;读文本文件时,VC++会将\r\n替换为\n,并且在读取到1AH时,认为文件结束。
MFC读写ini配置文件Email:liping_xiong@1.新建头文件如:ini.h,在编辑区域粘贴以下内容://///////////////////////////////////////////////////////////////////////// ini.h: interface for the Cini class.#if !defined(AFX_OPINI_H__CE3F8B7B_1ACA_46CC_A91C_F8E23FA9B063__INCLUDED _)#define AFX_OPINI_H__CE3F8B7B_1ACA_46CC_A91C_F8E23FA9B063__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#include <afxwin.h>class Cini{public:static DWORD ReadString (char *section, char * key, char stringtoread[], char * filename);static BOOL WriteString(LPCTSTR section, LPCTSTR key,char* stringtoadd, char*filename);Cini();virtual ~Cini();};#endif// !defined(AFX_OPINI_H__CE3F8B7B_1ACA_46CC_A91C_F8E23FA9B063__INCLUDED_)2.新建资源文件如:ini.cpp,在编辑区域黏贴以下内容://///////////////////////////////////////////////////////////////////////// ini.cpp: implementation of the Cini class.#include "stdafx.h"#include "ini.h"///////////////////////////////////////////////////////////////////////////Cini类的构造函数和析构函数Cini::Cini(){}Cini::~Cini(){}///////////////////////////////////////////////////////////////////////////写字符串到INI文件,GetLastError()函数用于返回写入失败void error(LPSTR lpszFunction){CHAR szBuf[80];DWORD dw = GetLastError();sprintf(szBuf, "%s failed: GetLastError returned %u\n",lpszFunction, dw);MessageBox(NULL, szBuf, "Error", MB_OK);ExitProcess(dw);}BOOL Cini::WriteString(LPCTSTR section, LPCTSTR key, char *stringtoadd, char *filename) {CHAR FilePath[255];GetModuleFileName(NULL,FilePath,255);(strrchr(FilePath,'\\'))[1] = 0;strcat(FilePath,filename);return ::WritePrivateProfileString(section,key,stringtoadd,FilePath);}///////////////////////////////////////////////////////////////////////////从INI文件中读取字符串DWORD Cini::ReadString(char *section, char * key, char stringtoread[], char * filename) {CHAR FilePath[255];GetModuleFileName(NULL,FilePath,255);(strrchr(FilePath,'\\'))[1] = 0;strcat(FilePath,filename);return ::GetPrivateProfileString(section, key,NULL,stringtoread,255,FilePath);}3.当程序加载的时候读配置文件:首先要在应用程序文件头部引用ini.h头文件如下:#include "ini.h"找到OnInitDialog()函数,在其下黏贴如下代码:// 保存ini各项值数组char szOption1[MAX_PATH];char szOption2[MAX_PATH];char szOption3[MAX_PATH];// 读取ini各项值Cini::ReadString("配置信息", "选项1", szOption1, "test.ini");Cini::ReadString("配置信息", "选项2", szOption2, "test.ini");Cini::ReadString("配置信息", "选项3", szOption3, "test.ini");m_strEdit1.Format("%s",szOption1);m_strEdit2.Format("%s",szOption2);m_strEdit3.Format("%s",szOption3);UpdateData(FALSE);说明:m_strEdit1,m_strEdit2,m_strEdit2是三个文本框对象的实例4.当卸载(关闭)程序的时候写配置文件;找到DestroyWindow()函数,在其下黏贴如下代码:UpdateData(TRUE);CString str1 = m_strEdit1;CString str2 = m_strEdit2;CString str3 = m_strEdit3;char *p1 = str1.GetBuffer(str1.GetLength()+1);char *p2 = str2.GetBuffer(str2.GetLength()+1);char *p3 = str3.GetBuffer(str3.GetLength()+1);Cini::WriteString("配置信息", "选项1", p1, "test.ini");Cini::WriteString("配置信息", "选项2", p2, "test.ini");Cini::WriteString("配置信息", "选项3", p3, "test.ini");说明:m_strEdit1,m_strEdit2,m_strEdit2是三个文本框对象的实例附工程视图及运行结果:Ini头文件Ini资源文件引用头文件引用头文件用户文件、应用程序文件对话框加载关闭对话框配置文件里的记录。
VC++读写ini配置文件VC++ 读写ini配置文件1.写ini文件把student.ini 放到C盘根目录下,路径也可以在程序里的两个函数调整BOOL WritePrivateProfileString(LPCTSTR lpAppName,LPCTSTR lpKeyName,LPCTSTR lpString,LPCTSTR lpFileName);其中各参数的意义LPCTSTR lpAppName 是INI文件中的一个字段名.LPCTSTR lpKeyName 是lpAppName下的一个键名,通俗讲就是变量名.LPCTSTR lpString 是键值,也就是变量的值,不过必须为LPCTSTR 型或CString型的. LPCTSTR lpFileName 是完整的INI文件名.2、读ini文件读整型UINT GetPrivateProfileInt(LPCTSTR lpAppName,LPCTSTR lpKeyName,INT nDefault,LPCTSTR lpFileName);nStudAge=GetPrivateProfileInt("StudentInfo","Age",10,"c:\\ \\stud\\\\student.ini"); 参数类型及说明lpApplicationName String,指定在其中查找条目的小节。
注意这个字串是不区分大小写的lpKeyName String,欲获取的设置项或条目。
这个支持不区分大小写nDefault Long,指定条目未找到时返回的默认值lpFileName String,初始化文件的名字。
如果没有指定完整的路径名,windows就会在Windows目录中搜索文件读字符串DWORD GetPrivateProfileString(LPCTSTR lpAppName,LPCTSTR lpKeyName,LPCTSTR lpDefault,LPTSTR lpReturnedString,DWORD nSize,LPCTSTR lpFileName);其中各参数的意义前二个参数与WritePrivateProfileString中的意义一样.lpDefault : 如果INI文件中没有前两个参数指定的字段名或键名,则将此值赋给变量.lpReturnedString : 接收INI文件中的值的CString对象,即目的缓存器.nSize : 目的缓存器的大小.lpFileName : 是完整的INI文件名.void CIniRWDlg::OnBtnwini() //响应WriteIniFile按钮的事件{// TODO: Add your control notification handler code here CString strName,strT emp;int nAge;strName="张三"; //写入的键nAge=12; //写入的值::WritePrivateProfileString("StudentInfo","Name",strName,"c: \\\\student.ini");strTemp.Format("%d",nAge);::WritePrivateProfileString("StudentInfo","Age",strTemp,"c:\\\ \student.ini");}void CIniRWDlg::OnBtnrini() //响应ReadIniFile按钮的事件{// TODO: Add your control notification handler code here CString strStudName;CString showIni;int nStudAge;GetPrivateProfileString("StudentInfo","Name","默认姓名",strStudName.GetBuffer(MAX_PATH),MAX_PATH,"c:\\\\stud ent.ini");nStudAge=GetPrivateProfileInt("StudentInfo","Age",10,"c:\\\ \student.ini");showIni.Format("student.ini\%s%c%d",strStudName,':',nStud Age); //字符串拼接GetDlgItem(IDC_SHOWINI)->SetWindowText(showIni); //显示到静态文本框中,该静态文本框的默认ID 为ID_STATIC 改成了IDC_SHOWINI.}注意:GetPrivateProfileString("StudentInfo","Name","默认姓名",strStudName.GetBuffer(MAX_PATH),MAX_PATH,"c:\\\\stud ent.ini");此处使用了strStudName.GetBuffer(MAX_PATH),所以后面任何对字符串strStudName的函数操作都会不起作用,要想进行这样的操作,必须先释放。
vc读写Excel⽂件的⽅法void ReadExcel(){CDatabase database;CString sSql;CString sItem1, sItem2 , sItem3;CString sDriver;CString sDsn;CString sFile,sPath;//获取主程序所在路径,存在sPath中GetModuleFileName(NULL,sPath.GetBufferSetLength(MAX_PATH+1),MAX_PATH);sPath.ReleaseBuffer();int nPos;nPos=sPath.ReverseFind ('\\');sPath=sPath.Left (nPos);sFile = sPath + "\\Demo.xls"; // 将被读取的Excel⽂件名// 检索是否安装有Excel驱动 "Microsoft Excel Driver (*.xls)"sDriver = GetExcelDriver();if (sDriver.IsEmpty()){// 没有发现Excel驱动AfxMessageBox("没有安装Excel驱动!");return;}// 创建进⾏存取的字符串sDsn.Format("ODBC;DRIVER={%s};DSN='';DBQ=%s", sDriver, sFile);TRY{// 打开数据库(既Excel⽂件)database.Open(NULL, false, false, sDsn);CRecordset recset(&database);// 设置读取的查询语句.注意此处表名的写法,excel⾥的表默认为系统表所以访问表时表名应为[表名$] sSql = "SELECT 考⽣编号,考⽣姓名,来源 ""FROM [student2$] ""ORDER BY 考⽣编号 ";// 执⾏查询语句recset.Open(CRecordset::forwardOnly, sSql, CRecordset::readOnly);// 获取查询结果while (!recset.IsEOF()){//读取Excel内部数值recset.GetFieldValue("考⽣编号", sItem1);recset.GetFieldValue("考⽣姓名", sItem2);recset.GetFieldValue("来源", sItem3);//显⽰记取的内容m_ExcelList.AddString( sItem1 + " --> "+sItem2 );// 移到下⼀⾏recset.MoveNext();}// 关闭数据库database.Close();}CATCH(CDBException, e){// 数据库操作产⽣异常时...AfxMessageBox("数据库错误: " + e->m_strError);}END_CATCH;}下⾯是第⼆种⽅法,这⾥涉及的原理要复杂⼀些了,传说中的OLE(对象链接与嵌⼊)技术在这⾥⽤上了,EXCEL.EXE作为⼀个组件服务器,应⽤程序作为客户端......,还是直接写过程吧,头晕晕的,只能平铺直述了.A,从classwizard中add class处from type library,去office的安装⽬录下引⼊excel.exe(这是office 2003的选择,其他版本都是⽤olb⽂件),服务器就算引⼊了,这时会弹出对话框,要求加⼊⼀些类,这些类都是⼀些接⼝,⾥⾯有⼤量的⽅法,类的对象表征着excel ⽂件的⼀个个部分,常⽤的有这⼏个_application,workbooks,_workbook,worksheets,_worksheet,Range,它们分别代表不同的意义._application代表了EXCEL服务器,workbooks表⽰整个Excel服务器(表现为⼀个.xls⽂件)⾥所有的表,(可以通过"新建"得到多个表,即MDI程序⾥的⼀个视窗⼀样,所有的视窗就是workbooks), _workbook就是⼀个表,相当于MDI中的⼀个视窗, worksheets表⽰所有的表单,每个表都可能有很多表单(建⽴⼀个Excel⽂件之后,打开,可以看到有sheet1,sheet2等,所有这些sheetn就组成了worksheets), _worksheet就表⽰⼀个表单, range表⽰元素的集合. 搞清楚上⾯这⼏个名词的意思⾮常重要. B,在dlg.h中声明下⾯⼏个变量:_Application exlapp; //组件服务器的各个classes_Workbook wbk;Workbooks wbks;_Worksheet wht;Worksheets whts;LPDISPATCH lpDisp;并在app.cpp的InitInstance⽅法中加⼊下⾯两句AfxInitOle(); AfxEnableControlContainer();C,这⾥我没有像上⾯⼀样完全⽤程序来⽣成⼀个Excel⽂件,⽽是在开始时就在当前⽬录下⽣成了⼀个Excel⽂件,在对话框上我设置了两个按钮,下⾯是"显⽰"按钮的代码://创建Excel服务器if(!exlapp.CreateDispatch("Excel.Application")){AfxMessageBox("⽆法启动Excel服务器!");return;}COleVariant avar((long)DISP_E_PARAMNOTFOUND,VT_ERROR);exlapp.SetVisible(TRUE);//使Excel可见exlapp.SetUserControl(TRUE);//允许其它⽤户控制Excel,否则Excel将⼀闪即逝.//Open an excel filechar path[MAX_PATH];GetCurrentDirectory(MAX_PATH,path);CString strPath = path;strPath += "\\VCOpExcel";wbks.AttachDispatch(exlapp.GetWorkbooks());lpDisp=wbks.Open(strPath,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar);wbks.ReleaseDispatch();exlapp.ReleaseDispatch();D,与上⾯第⼀种⽅法⼀样,可以插⼊记录:UpdateData(); //读⼊数据if (""==m_name) //判断名字输⼊有效{MessageBox("Please input a right name");return;}if (0>=m_age||100<=m_age) //判断年龄输⼊有效{MessageBox("Please input a right age");return;}char *p=strupr(_strdup(m_gener));if (strcmp(p,"FEMALE")&&strcmp(p,"MALE")) //判断性别输⼊有效{MessageBox("Please input a right gener");return;}Range range;Range usedRange;COleVariant avar((long)DISP_E_PARAMNOTFOUND,VT_ERROR);if(!exlapp.CreateDispatch("Excel.Application")) //启动服务器{AfxMessageBox("⽆法启动Excel服务器!");return;}char path[MAX_PATH];GetCurrentDirectory(MAX_PATH,path);CString strPath = path;strPath += "\\VCOpExcel";wbks.AttachDispatch(exlapp.GetWorkbooks());lpDisp=wbks.Open(strPath, //初始化.avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar);wbk.AttachDispatch(lpDisp);whts.AttachDispatch(wbk.GetWorksheets());lpDisp=wbk.GetActiveSheet();wht.AttachDispatch(lpDisp);usedRange.AttachDispatch(wht.GetUsedRange());range.AttachDispatch(usedRange.GetRows());long iRowNum=range.GetCount();//已经使⽤的⾏数range.AttachDispatch(wht.GetCells());range.SetItem(COleVariant(long(iRowNum+1)),COleVariant(long(1)),COleVariant(m_name)); range.SetItem(COleVariant(long(iRowNum+1)),COleVariant(long(2)),COleVariant(m_age)); range.SetItem(COleVariant(long(iRowNum+1)),COleVariant(long(3)),COleVariant(m_gener)); wbk.Save();wbk.Close(avar,COleVariant(strPath),avar);wbks.Close();exlapp.Quit();第⼆种⽅法完。
CC++关于如何读写ini配置⽂件(⼩结)我们可能经常⽤到配置⽂件ini⽂件来获取或者保存参数信息,在VC中其函数中主要⽤到的有:读取1. 读取字符DWORD GetPrivateProfileString(LPCTSTR lpAppName, // INI⽂件中的⼀个字段名[节名]可以有很多个节名LPCTSTR lpKeyName, // lpAppName 下的⼀个键名,也就是⾥⾯具体的变量名LPCTSTR lpDefault, // 如果lpReturnedString为空,则把个变量赋给lpReturnedStringLPTSTR lpReturnedString, // 存放键值的指针变量,⽤于接收INI⽂件中键值(数据)的接收缓冲区DWORD nSize, // lpReturnedString的缓冲区⼤⼩LPCTSTR lpFileName // INI⽂件的路径);2. 读取整型值 (返回值为读到的整)UINT GetPrivateProfileInt(LPCTSTR lpAppName, // INI⽂件中的⼀个字段名[节名]可以有很多个节名LPCTSTR lpKeyName, // lpAppName 下的⼀个键名,也就是⾥⾯具体的变量名INT nDefault, // 如果没有找到指定的数据返回,则把个变量值赋给返回值LPCTSTR lpFileName // INI⽂件的路径);写⼊1. 写⼊字符BOOL WritePrivateProfileString(LPCTSTR lpAppName, // INI⽂件中的⼀个字段名[节名]可以有很多个节名LPCTSTR lpKeyName, // lpAppName 下的⼀个键名,也就是⾥⾯具体的变量名LPCTSTR lpString, // 键值,也就是数据LPCTSTR lpFileName // INI⽂件的路径);2. 写⼊整型读写INI⽂件时相对路径和绝对路径都可以,根据实际情况选择 "..\\IniFileName.ini" // 这样的为相对路径 "D:\\IniFileName.ini" // 这样的为绝对路径MAX_PATH:是微软最⼤路径占的字节所设的宏 写⼊的ini⽂件分为:节、键名、键值 举个栗⼦: // XX.ini [串⼝配置] 波特率=19200有了理论,再看看实践的demo:写INI⽂件:LPTSTR lpPath = new char[MAX_PATH];strcpy(lpPath, "D:\\IniFileName.ini");WritePrivateProfileString("LiMing", "Sex", "Man", lpPath);WritePrivateProfileString("LiMing", "Age", "20", lpPath);WritePrivateProfileString("Fangfang", "Sex", "Woman", lpPath);WritePrivateProfileString("Fangfang", "Age", "21", lpPath);delete [] lpPath;INI⽂件如下:[LiMing]Sex=ManAge=20[Fangfang]Sex=WomanAge=21读INI⽂件:TCHAR FPath[128];::GetCurrentDirectory(MAX_PATH, FPath);strcat(FPath, ".\\Config.ini");CFile ConfigFile;if(!ConfigFile.Open(FPath, CFile::modeCreate||CFile::modeRead, NULL)){AfxMessageBox("打开Config.ini配置⽂件失败!!!");return FALSE;}ConfigFile.Close();LPTSTR lpPath = new char[MAX_PATH];LPTSTR LiMingSex = new char[6];int LiMingAge;LPTSTR FangfangSex = new char[6];int FangfangAge;strcpy(lpPath, "..\\IniFileName.ini");GetPrivateProfileString("LiMing", "Sex", "", LiMingSex, 6, lpPath);LiMingAge = GetPrivateProfileInt("LiMing", "Age", 0, lpPath);GetPrivateProfileString("Fangfang", "Sex", "", FangfangSex, 6, lpPath);FangfangAge = GetPrivateProfileInt("Fangfang", "Age", 0, lpPath);delete [] lpPath;配置⽂件中经常⽤到ini⽂件,在VC中其函数分别为:写⼊.ini⽂件:bool WritePrivateProfileString(LPCTSTR lpAppName,LPCTSTR lpKeyName,LPCTSTR lpString,LPCTSTR lpFileName);读取.ini⽂件:DWORD GetPrivateProfileString(LPCTSTR lpAppName,LPCTSTR lpKeyName,LPCTSTR lpDefaut,LPSTR lpReturnedString,DWORD nSize,LPCTSTR lpFileName);读取整形值:UINT GetPrivateProfileInt(LPCTSTR lpAppName,LPCTSTR lpKeyName,INT nDefault,LPCTSTR lpFileName);其中个参数的意思:LPCTSTR lpAppName ------- INI⽂件中的⼀个字段名LPCTSTR lpKeyName -------- lpAppName 下的⼀个键名,也就是⾥⾯具体的变量名LPCTSTR lpString ---------是键值,也就是变量的值,必须为LPCTSTR或CString类型LPCTSTR lpFileName --------完整的INI⽂件路径名LPCTSTR lpDefaut ----------如果没有其前两个参数值,则将此值赋给变量LPSTR lpReturnedString --------接收INI⽂件中的值的CString对象,即接收缓冲区DWORD nSize ------接收缓冲区的⼤⼩例⼦:CString StrName,Strtemp;int nAge;StrName = "jacky";nAge = 13;WritePrivateProfileString("Student","Name",StrName,"c:\\setting.ini");结果:(INI⽂件中显⽰如下:)[Student]Name=jacky读取:CString SName;GetPrivateProfileString("Student","Name","DefaultName",SName.GetBuffer(MAX_LENGTH),MAX_LENGTH,"c:\\setting.ini");结果:SName = "jacky";这⾥需要注意点就是⽤完GetBuffer函数后⼀定要释放(⽤SName.ReleaseBuffer()函数),不然后⾯再⽤到SName 的其他⼦函数就会失灵。
c读取配置文件的方法在C语言中读取配置文件是非常常见的操作,它可以方便地管理程序的一些参数和选项,让程序更加灵活和易于维护。
下面是一些常见的方法:1. 使用标准库函数fopen和fscanf这是最常见的方法之一,使用标准库函数fopen和fscanf来逐行读取配置文件中的内容。
具体实现步骤如下:a. 使用fopen打开配置文件,获取文件指针。
b. 使用fscanf读取每一行的内容,根据具体的配置格式进行解析。
c. 关闭文件指针。
示例代码:FILE *fp;char buf[1024];int value;fp = fopen('config.ini', 'r');if (fp == NULL){printf('Cannot open config file.');return -1;}while (fgets(buf, sizeof(buf), fp) != NULL){if (sscanf(buf, 'key=%d', &value) == 1){// 解析成功,使用读取到的值进行后续操作printf('value=%d', value);}}fclose(fp);2. 使用ini配置文件解析库ini配置文件解析库是一个专门用来解析ini配置文件的库,它能够快速、简单地读取和修改ini文件中的配置项。
具体实现步骤如下:a. 下载并安装ini解析库。
b. 使用ini_parse函数读取配置文件。
c. 使用ini_get函数获取配置项的值。
示例代码:#include 'ini.h'int handler(void* user, const char* section, const char* name,const char* value)if (strcmp(section, 'config') == 0 && strcmp(name, 'key') == 0){// 获取配置项的值int* pvalue = (int*)user;*pvalue = atoi(value);}return 1;}int main(){int value;if (ini_parse('config.ini', handler, &value) < 0){printf('Cannot open config file.');return -1;}printf('value=%d', value);return 0;3. 使用XML配置文件解析库XML配置文件解析库是一个专门用来解析XML格式的配置文件的库,它能够解析复杂的XML文件,并且提供了灵活的配置项操作方式。
C++读写ini配置⽂件实现过程详解在Windows的VC下读ini⽂件例如:在D:\test.ini⽂件中[Font]name=宋体size= 12ptcolor = RGB(255,0,0)上⾯的=号两边可以加空格,也可以不加⽤GetPrivateProfileInt()和GetPrivateProfileString()[section]key=string..获取integerUINT GetPrivateProfileInt(LPCTSTR lpAppName, // section nameLPCTSTR lpKeyName, // key nameINT nDefault, // return value if key name not foundLPCTSTR lpFileName // initialization file name);注意:lpAppName和lpKeyName不区分⼤⼩写,当获得integer <0,那么返回0。
lpFileName 必须是绝对路径,因相对路径是以C:\windows\DWORD GetPrivateProfileString(LPCTSTR lpAppName, // section nameLPCTSTR lpKeyName, // key nameLPCTSTR lpDefault, // default stringLPTSTR lpReturnedString, // destination bufferDWORD nSize, // size of destination bufferLPCTSTR lpFileName // initialization file name);注意:lpAppName和lpKeyName不区分⼤⼩写,若lpAppName为NULL,lpReturnedString缓冲区内装载这个ini⽂件所有⼩节的列表,若为lpKeyName=NULL,就在lpReturnedString缓冲区内装载指定⼩节所有项的列表。
VC6.0编的“文件读写”的两种方式(MFC和基于对话框)软件实验三:基于对话框的MFC程序实现文件读写操作实例一:操作步骤:1、新建“MFC APPWIZARD(EXE)”,选择文件路径,输入文件名,选择应用程序类型为“基本对话框”,按上图添加各控件2、按下表修改各控件的ID号,添加成员函数和消息函数控件的ID号,选择mumber variables面板,单击add variable按钮,添加成员变量,并选择变量类型。
3、写入文件1)在“基于对话框的文件读写Dlg.h”文件中定义变量(粗体字为此处添加的代码)class CMyDlg : public CDialog{// Constructionpublic://定义变量CString strFileName;//文件名CString strFilePath;//文件路径BOOL IsTextFile(CString& rFile);//判断文件类型是否正确CMyDlg(CWnd* pParent = NULL); // standard constructor………}2)双击下压按钮“写入文件”,编写“写入文件”的消息处理函数void CMyDlg::OnButtonWrite() //单击“写入到文件”按钮{// TODO: Add your control notification handler code hereUpdateData(true);CFile file;CFileDialog filedlg(0,//1-文件打开,0-文件另存为".txt|*.*",NULL,OFN_OVERWRITEPROMPT,"文本文件(*.txt)|*.txt|All Files(*.*)|*.*||",NULL);if(filedlg.DoModal()==IDOK)strFileName=filedlg.GetFileName();//获得文件名if(strFileName==""){AfxMessageBox("请输入文件名");return;}file.Open(strFileName,CFile::modeCreate|CFile::modeWrite);//将数据写入文件int length=m_WriteString.GetLength();//获取文件长度file.Write((LPCTSTR)m_WriteString,length);//获取有关文件的信息CString AfxMessageBox("已保存到文件:"+strFileName+"!");//保存结束提示strFilePath=file.GetFilePath();//获得文件的路径file.Close();//关闭文件}4、查看文件路径双击下压按钮“查看文件路径”,编写“查看文件路径”的消息处理函数void CMyDlg::OnButtonFilepath() //查看文件路径{// TODO: Add your control notification handler code herem_FilePath=strFilePath;UpdateData(false);}5、读入文件1)定义判断文件类型是否正确的函数(粗体字为此处添加的代码)class CMyDlg : public CDialog{// Constructionpublic://定义变量CString strFileName;//文件名CString strFilePath;//文件路径BOOL IsT extFile(CString& rFile);//判断文件类型是否正确CMyDlg(CWnd* pParent = NULL); // standard constructor………}2)编写IsTextFile函数BOOL CMyDlg::IsTextFile(CString &rFile)//判断文件类型是否正确{CStringList strList;CString str(rFile);strList.AddHead(".TXT");strList.AddHead(".SYS");strList.AddHead(".BA T");strList.AddHead(".DA T");str=str.Right(4);//文件名的右边四位字符str.MakeUpper();//转换成大写return(strList.Find(str))?TRUE:FALSE;}3)在“基于对话框的文件读写Dlg.cpp”文件开头添加头文件#include "fstream.h"//添加的头文件4)单击下压按钮“读入文件”,编写下压按钮“读入文件”的消息函数void CMyDlg::OnButtonRead(){// TODO: Add your control notification handler code herefstream f1;//定义文件流对象char s[200];CFileDialog filedlg(1,//1-文件打开,0-文件另存为".txt|*.*",NULL,OFN_OVERWRITEPROMPT,"文本文件(*.txt)|*.txt|All Files(*.*)|*.*||",NULL);if(filedlg.DoModal()==IDOK){UpdateData(true);strFileName=filedlg.GetFileName();//获得文件名if(!IsTextFile(strFileName))//判断文件类型是否正确{AfxMessageBox("文件类型不正确");return;}f1.open(strFileName,ios::in|ios::nocreate);while(!f1.eof()){f1.getline(s,255);m_strRead=m_strRead+"\r\n"+s;//添加文件中的文本到编辑框UpdateData(false);}AfxMessageBox(strFileName+"文件读入完毕");//保存结束提示f1.close();//关闭文件流}}6、运行程序1)在写入文件的编辑框中输入内容,单击“写入文件”按钮,并可选择路径保存该文件。
Winform—C#读写config配置⽂件现在FrameWork2.0以上使⽤的是:ConfigurationManager或WebConfigurationManager。
并且AppSettings属性是只读的,并不⽀持修改属性值.⼀、如何使⽤ConfigurationManager?1、添加引⽤:添加System.configguration2、引⽤空间3、config配置⽂件配置节常⽤配置节:(1)普通配置节<appSettings> <add key="COM1" value="COM1,9600,8,None,1,已启⽤" /></appSettings>(2)数据源配置节<connectionStrings> <add name="kyd" connectionString="server=.;database=UFDATA_999_2017;user=sa;pwd=123"/> </connectionStrings>(3)⾃定义配置节⼆、config⽂件读写1、依据连接串名字connectionName返回数据连接字符串//依据连接串名字connectionName返回数据连接字符串public static string GetConnectionStringsConfig(string connectionName){//指定config⽂件读取string file = System.Windows.Forms.Application.ExecutablePath;System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(file);string connectionString =config.ConnectionStrings.ConnectionStrings[connectionName].ConnectionString.ToString();return connectionString;}2、更新连接字符串///<summary>///更新连接字符串///</summary>///<param name="newName">连接字符串名称</param>///<param name="newConString">连接字符串内容</param>///<param name="newProviderName">数据提供程序名称</param>public static void UpdateConnectionStringsConfig(string newName, string newConString, string newProviderName){//指定config⽂件读取string file = System.Windows.Forms.Application.ExecutablePath;Configuration config = ConfigurationManager.OpenExeConfiguration(file);bool exist = false; //记录该连接串是否已经存在//如果要更改的连接串已经存在if (config.ConnectionStrings.ConnectionStrings[newName] != null){exist = true;}// 如果连接串已存在,⾸先删除它if (exist){config.ConnectionStrings.ConnectionStrings.Remove(newName);}//新建⼀个连接字符串实例ConnectionStringSettings mySettings =new ConnectionStringSettings(newName, newConString, newProviderName);// 将新的连接串添加到配置⽂件中.config.ConnectionStrings.ConnectionStrings.Add(mySettings);// 保存对配置⽂件所作的更改config.Save(ConfigurationSaveMode.Modified);// 强制重新载⼊配置⽂件的ConnectionStrings配置节ConfigurationManager.RefreshSection("connectionStrings");}3、返回*.exe.config⽂件中appSettings配置节的value项///<summary>///返回*.exe.config⽂件中appSettings配置节的value项///</summary>///<param name="strKey"></param>///<returns></returns>public static string GetAppConfig(string strKey){string file = System.Windows.Forms.Application.ExecutablePath;Configuration config = ConfigurationManager.OpenExeConfiguration(file);foreach (string key in config.AppSettings.Settings.AllKeys){if (key == strKey){return config.AppSettings.Settings[strKey].Value.ToString();}}return null;}4、在*.exe.config⽂件中appSettings配置节增加⼀对键值对///<summary>///在*.exe.config⽂件中appSettings配置节增加⼀对键值对///</summary>///<param name="newKey"></param>///<param name="newValue"></param>public static void UpdateAppConfig(string newKey, string newValue){string file = System.Windows.Forms.Application.ExecutablePath;Configuration config = ConfigurationManager.OpenExeConfiguration(file);bool exist = false;foreach (string key in config.AppSettings.Settings.AllKeys){if (key == newKey){exist = true;}}if (exist){config.AppSettings.Settings.Remove(newKey);}config.AppSettings.Settings.Add(newKey, newValue);config.Save(ConfigurationSaveMode.Modified);ConfigurationManager.RefreshSection("appSettings");}5、修改IP地址// 修改system.serviceModel下所有服务终结点的IP地址public static void UpdateServiceModelConfig(string configPath, string serverIP){Configuration config = ConfigurationManager.OpenExeConfiguration(configPath);ConfigurationSectionGroup sec = config.SectionGroups["system.serviceModel"];ServiceModelSectionGroup serviceModelSectionGroup = sec as ServiceModelSectionGroup; ClientSection clientSection = serviceModelSectionGroup.Client;foreach (ChannelEndpointElement item in clientSection.Endpoints){string pattern = @"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b";string address = item.Address.ToString();string replacement = string.Format("{0}", serverIP);address = Regex.Replace(address, pattern, replacement);item.Address = new Uri(address);}config.Save(ConfigurationSaveMode.Modified);ConfigurationManager.RefreshSection("system.serviceModel");}// 修改applicationSettings中App.Properties.Settings中服务的IP地址public static void UpdateConfig(string configPath, string serverIP){Configuration config = ConfigurationManager.OpenExeConfiguration(configPath);ConfigurationSectionGroup sec = config.SectionGroups["applicationSettings"];ConfigurationSection configSection = sec.Sections["DataService.Properties.Settings"];ClientSettingsSection clientSettingsSection = configSection as ClientSettingsSection;if (clientSettingsSection != null){SettingElement element1 = clientSettingsSection.Settings.Get("DataService_SystemManagerWS_SystemManagerWS");if (element1 != null){clientSettingsSection.Settings.Remove(element1);string oldValue = element1.Value.ValueXml.InnerXml;element1.Value.ValueXml.InnerXml = GetNewIP(oldValue, serverIP);clientSettingsSection.Settings.Add(element1);}SettingElement element2 = clientSettingsSection.Settings.Get("DataService_EquipManagerWS_EquipManagerWS");if (element2 != null){clientSettingsSection.Settings.Remove(element2);string oldValue = element2.Value.ValueXml.InnerXml;element2.Value.ValueXml.InnerXml = GetNewIP(oldValue, serverIP);clientSettingsSection.Settings.Add(element2);}}config.Save(ConfigurationSaveMode.Modified);ConfigurationManager.RefreshSection("applicationSettings");}private static string GetNewIP(string oldValue, string serverIP){string pattern = @"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b";string replacement = string.Format("{0}", serverIP);string newvalue = Regex.Replace(oldValue, pattern, replacement);return newvalue;}修改IP地址config 读写⽅法using System.Configuration;//省略其他代码public SalesOrderData(){string str = "";str = ConfigurationManager.ConnectionStrings["kyd"].ToString();conn = new SqlConnection(str);cmd = conn.CreateCommand();}实际应⽤:1、获取配置节的值button1 点击获取配置节<appSettings>指定key的value值button2 点击获取配置节<connectionStrings>指定name的connectionString值结果为:2、修改配置节的值button1 点击获取配置节<appSettings>指定key的value值button2 点击修改配置节<connectionStrings>指定key的value值为⽂本框的值button3 点击获取配置节<appSettings>指定key新的value值结果为:此时配置⽂件key1的value值为,获取key值仍为修改前的值如何重置为修改前的值?如何保存修改后的值?。
在Visual C++ 6.0下对Windows配置设置文件的存取访问方法的详细介绍。
一、引言0不论是对于程序开发人员还是软件应用人员,一定不会对扩展名为"ini"的文件感到陌生,不仅Windows操作系统将大名鼎鼎的win.ini作为记录当前系统状态,并根据其记录内容对系统进行配置的一种便捷的方法,而且众多的应用软件也广泛地使用该类型的配置文件来对软件进行记录、配置。
本文就针对配置设置文件的使用展开讨论,以期能为软件状态的记录与设置寻求一种方便简洁的实现方法。
0二、配置设置文件概述0配置设置文件是Windows操作系统下的一种特殊化的ASCII文件,以"ini"为文件扩展名。
该文件也被称做是初始化文件(initialization file)和概要文件(profile),通常应用程序可以拥有自己的配置设置文件来存储自己的状态信息,一般来说私有的配置设置文件比较小,可以减少程序在初始化时读取配置文件时的信息量,从而可以提高程序的启动速度、提高应用程序和系统的性能。
但如待存取的信息涉及到Windows 系统环境或是其他的应用程序时才必须在Windows系统的配置文件win.ini中记录并在访问的同时发送出消息WM_WININICHANGE给所有的顶层窗口,通知其他的程序系统的配置文件已做了更改。
但由于win.ini中不仅记录了系统的有关信息,也存储着许多其他应用软件的一些配置数据,所以访问的数据量要远比私有的配置文件大的多。
0配置文件里的信息之所以能为系统和众多的软件所读取并识别,是由于其内部对数据的存取采用了预先约定好的"项-值对(entry-value pairs)"存储结构来对待存取的数据进行分门别类地进行条理清晰的存储。
我们可以打开系统目录下的win.ini文件:0[windows]load=run=NullPort=None0[Desktop]WallpaperStyle=2Pattern=(无)0[intl]s2359=PMiCountry=86 0可见,配置文件把信息分成若干"节",节标题放在方括号中,如[Desktop]就是Desktop节,在一个节内包含了一些与之相关相近的"项",并通过等号对其进行赋值。
vc 用函数读写INI配置文件ini文件(即Initialization file),这种类型的文件中通常存放的是一个程序的初始化信息。
ini文件由若干个节(Section)组成,每个Section由若干键(Key)组成,每个Key可以赋相应的值。
读写ini文件实际上就是读写某个的Section中相应的Key的值,而这只要借助几个函数即可完成。
一、向ini文件中写入信息的函数1. 把信息写入系统的win.ini文件BOOL WriteProfileString(LPCTSTR lpAppName, // 节的名字,是一个以0结束的字符串LPCTSTR lpKeyName, // 键的名字,是一个以0结束的字符串。
若为NULL,则删除整个节LPCTSTR lpString // 键的值,是一个以0结束的字符串。
若为NULL,则删除对应的键)2. 把信息写入自己定义的.ini文件BOOL WritePrivateProfileString(LPCTSTR lpAppName, // 同上LPCTSTR lpKeyName, // 同上LPCTSTR lpString, // 同上LPCTSTR lpFileName // 要写入的文件的文件名。
若该ini文件与程序在同一个目录下,也可使用相对//路径,否则需要给出绝度路径。
)如:::WriteProfileString("Test","id","xym");//在win.ini中创建一个Test节,并在该节中创建一个键id,其值为xym::WritePrivateProfileString("Test","id","xym","d:\\vc\\Ex1\\ex1.ini" );//在Ex1目录下的ex1.ini中创建一个Test节,并在该节中创建一个键id,其值为xym//若Ex1.ini文件与读写该文件的程序在同一个目录下,则上面语句也可写为:::WritePrivateProfileString("Test","id","xym",".\\ex1.ini");需要注意的是,C系列的语言中,转义字符'\\'表示反斜线'\'。
另外,当使用相对路径时,\\前的.号不能丢掉了。
二、从ini文件中读取数据的函数1、从系统的win.ini文件中读取信息(1) 读取字符串DWORD GetProfileString(LPCTSTR lpAppName, // 节名LPCTSTR lpKeyName, // 键名,读取该键的值LPCTSTR lpDefault, // 若指定的键不存在,该值作为读取的默认值LPTSTR lpReturnedString, // 一个指向缓冲区的指针,接收读取的字符串DWORD nSize // 指定lpReturnedString指向的缓冲区的大小)如:CString str;::GetProfileString("Test","id","Error",str.GetBuffer(20),20);(2) 读取整数UINT GetProfileInt(LPCTSTR lpAppName, // 同上LPCTSTR lpKeyName, // 同上INT nDefault // 若指定的键名不存在,该值作为读取的默认值)如使用以下语句写入了年龄信息:::WriteProfileString("Test","age","25");//在win.ini中创建一个Test节,并在该节中创建一个键age,其值为25则可用以下语句读取age键的值:int age;age=::GetProfileInt("Test","age",0);2、从自己的ini文件中读取信息(1) 读取字符串DWORD GetPrivateProfileString(LPCTSTR lpAppName, // 同1(1)LPCTSTR lpKeyName, // 同1(1)LPCTSTR lpDefault, // 同1(1)LPTSTR lpReturnedString, // 同1(1)DWORD nSize, // 同1(1)LPCTSTR lpFileName // 读取信息的文件名。
若该ini文件与程序在同一个目录下,也可使用相//对路径,否则需要给出绝度路径。
)如:CString str;::GetPrivateProfileString("Test","id","Error",str.GetBuffer(20),20,".\\ex1.ini");或:::GetPrivateProfileString("Test","id","Error",str.GetBuffer(20),20,"d:\\vc\\Ex1\\ex1.ini");(2) 读取整数UINT GetPrivateProfileInt(LPCTSTR lpAppName, // 同上LPCTSTR lpKeyName, // 同上INT nDefault, // 若指定的键名不存在,该值作为读取的默认值LPCTSTR lpFileName // 同上)如使用以下语句写入了年龄信息:::WritePrivateProfileString("Test","age","25",".\\ex1.ini");//在ex1.ini中创建一个Test节,并在该节中创建一个键age,其值为25则可用以下语句读取age键的值:int age;age=::GetPrivateProfileInt("Test","age",0,".\\ex1.ini");三、删除键值或节回顾一下WriteProfileString函数的说明BOOL WriteProfileString(LPCTSTR lpAppName, // 节的名字,是一个以0结束的字符串LPCTSTR lpKeyName, // 键的名字,是一个以0结束的字符串。
若为NULL,则删除整个节LPCTSTR lpString // 键的值,是一个以0结束的字符串。
若为NULL,则删除对应的键)由此可见,要删除某个节,只需要将WriteProfileString第二个参数设为NULL即可。
而要删除某个键,则只需要将该函数的第三个参数设为NULL即可。
这是删除系统的win.ini中的节或键,类似的,要删除自己定义的ini文件中的节或键,也可做相同的操作。
如:::WriteProfileString("Test",NULL,NULL); //删除win.ini中的Test节::WriteProfileString("Test","id",NULL); //删除win.ini中的id键::WritePrivateProfileString("Test",NULL,NULL,".\\ex1.ini"); //删除ex1.ini中的Test节::WritePrivateProfileString("Test","id",NULL,".\\ex1.ini"); //删除ex1.ini中的id键四、如何判断一个ini文件中有多少个节要判断一个ini文件中有多少个节,最简单的办法就是将所有的节名都找出来,然后统计节名的个数。
而要将所有的节名找出来,使用GetPrivateProfileSectionNames函数就可以了,其原型如下:DWORD GetPrivateProfileSectionNames(LPTSTR lpszReturnBuffer, // 指向一个缓冲区,用来保存返回的所有节名DWORD nSize, // 参数lpszReturnBuffer的大小LPCTSTR lpFileName // 文件名,若该ini文件与程序在同一个目录下,//也可使用相对路径,否则需要给出绝度路径)下面的是用来统计一个ini文件中共有多少个节的函数,当然,如果需要同时找到每个节中的各个键及其值,根据找到节名就可以很容易的得到了。
/*统计共有多少个节节名的分离方法:若chSectionNames数组的第一字符是'\0'字符,则表明有0个节。
否则,从chSectionNames数组的第一个字符开始,顺序往后找,直到找到一个'\0'字符,若该字符的后继字符不是 '\0'字符,则表明前面的字符组成一个节名。
若连续找到两个'\0'字符,则统计结束*/int CTestDlg::CalcCount(void){TCHAR chSectionNames[2048]={0}; //所有节名组成的字符数组char * pSectionName; //保存找到的某个节名字符串的首地址int i; //i指向数组chSectionNames的某个位置,从0开始,顺序后移int j=0; //j用来保存下一个节名字符串的首地址相对于当前i的位置偏移量int count=0; //统计节的个数//CString name;//char id[20];::GetPrivateProfileSectionNames(chSectionNames,2048,".\\ex1.ini");for(i=0;i<2048;i++,j++){if(chSectionNames[0]=='\0')break; //如果第一个字符就是0,则说明ini中一个节也没有if(chSectionNames[i]=='\0'){pSectionName=&chSectionNames[i-j]; //找到一个0,则说明从这个字符往前,减掉j个偏移量,//就是一个节名的首地址j=-1; //找到一个节名后,j的值要还原,以统计下一个节名地址的偏移量//赋成-1是因为节名字符串的最后一个字符0是终止符,不能作为节名//的一部分/*::GetPrivateProfileString(pSectionName,"id","Error",id,20,". \\ex1.ini");name.Format("%s",id);*///在获取节名的时候可以获取该节中键的值,前提是我们知道该节中有哪些键。