![]() |
中国DOS联盟-- 联合DOS 推动DOS 发展DOS --联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum |
| 游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟 |
|
中国DOS联盟论坛 现在时间是 2026-10-31 17:53 |
共 47,815 主题排行 / 349,930 发帖 / 今日 0 篇 / 48,290 会员排行 |
| DOS开发编程 & 发展交流 (开发室) » 怎样用C编写读取INI的配置文件? |
| 可打印版本 3,361 / 16 |
| 第1楼 profree | 发表于 2004-11-14 00:00 |
| 中级用户 发帖 132 积分 478 | |
|
怎样用C编写读取INI的配置文件? 怎样用C编写读取INI的配置文件?
|
|
| 第2楼 qb45 | 发表于 2004-11-15 00:00 |
| 高级用户 发帖 194 积分 677 | |
|
INI的配置文件实际上是文本文件,不知道c语言有哪几种打开方式,用qb的话用OPEN "TEST.INI " FOR INPUT AS #1如果你想用2进制方式打开也行,也是可以读出的OPEN "TEST.INI " FOR BINARY AS #1
|
|
| 第3楼 profree | 发表于 2004-11-15 00:00 |
| 中级用户 发帖 132 积分 478 | |
|
对,是文本文件,但需要作一些判断,键名是多少,键值是多少,我找到一个外国人编写的DOS下inifile的文件,非常不错,但就是没有源代码呀,
|
|
| 第4楼 qb45 | 发表于 2004-11-15 00:00 |
| 高级用户 发帖 194 积分 677 | |
|
可惜偶不懂c!
|
|
| 第5楼 bush | 发表于 2004-11-19 00:00 |
| 银牌会员 发帖 730 积分 2,165 | |
|
把那個外國人的程序發來試試,大家一起分析
|
|
| 第6楼 profree | 发表于 2004-11-20 00:00 |
| 中级用户 发帖 132 积分 478 | |
| 第7楼 郭恒 | 发表于 2004-11-24 00:00 |
| 中级用户 发帖 39 积分 225 | |
|
可在www.firstsail.b2b.cn网站中的“软件作品”免费下载,其是一个类 1:“注册表”类是CRegister,DOS版本不支持多线程中的同步,但WINDOWS版本支持多线程中的同步 ;本接口能够将在键值后面的注释,在修改后仍能正确的写回。2:主要接口如下所示 FILE* GetFile(){return(m_pFile);}; //判断文件是否装载成功 static int Atoi(char *pStr);//计算16进制值 static int GetCount(char *pStr,char nCh);//计算”串”中的”某一字符”的出现频率 static char* GetString(int nIndex,char nCh,char *pStrSource);//从串中得到以某字符分隔的串 static char* TrimLeft(char *pStr);//将”串”中的左空格删去 static char* TrimRight(char *pStr); //将”串”中的右空格删去 static BOOL IsProfileBoolen(char *pStr); //判断”串”是否表达真 //读键值 char* GetProfileString(char *pStrSegment,char *pStrKey,char *pStrDefault=""
; //读字符串 long GetProfileLong(char *pStrSegment,char *pStrKey,long lDefault=0L);//读32位整数 WORD GetProfileWord(char *pStrSegment,char *pStrKey,WORD wDefault);//读16位无符号整数 int GetProfileInt(char *pStrSegment,char *pStrKey, int nDefault);//读16位有符号整数 float GetProfileFloat(char *pStrSegment,char *pStrKey,float fDefault);//读单精度浮点数 double GetProfileDouble(char *pStrSegment,char *pStrKey,double dbDefault);//读双精度浮点数 //写键值 BOOL WriteProfileString(char *pStrSegment,char *pStrKey,char *pStrDefault);//写字符串 BOOL WriteProfileLong(char *pStrSegment,char *pStrKey,long lDefault);//写32位有符号整数 BOOL WriteProfileWord(char *pStrSegment,char *pStrKey,WORD wDefault);//写16位无符号整数 BOOL WriteProfileInt(char *pStrSegment,char *pStrKey, int nDefault);//写16位于符号整数 BOOL WriteProfileFloat(char *pStrSegment,char *pStrKey,float fDefault);//写单精度浮点数 BOOL WriteProfileDouble(char *pStrSegment,char *pStrKey,double dbDefault);//写双精度浮点数3:使用举例#include “Symbol.h”#include “Register.h”BOOL MySample_27(){CRegister* pRegister = new CRegister("Config.Ini" ; //加载文件if (pRegister == NULL || NULL == pRegister->GetFile()) //判断是否加载成功{ DELETE(pRegister); return(FALSE);}//读一整数int nHello = pRegister->GetProfileInt(” Boot”, “Hello”, 37);//读一无符号整数int nSign = pRegister->GetProfileInt(” Boot”, “Sign”, 37u);//读一长整数long lgGood = pRegister->GetProfileLong(” Boot”, “Good”, 37L);//读单精度浮点数float fData = pRegister->GetProfileFloat(” Boot”, ”LiPing”, 0.5f);//读双精度浮点数double dbData = pRegister->GetProfileDouble(” Boot”, ”Line4”, 3.7);//读布尔变量BOOL bBoolV = pRegister->IsProfileBoolen(pRegister->GetProfileString(“Boot”,”BootV”,”True”));//读字符串char strPrintName;_fstrcpy(strPrintName, pRegister->GetProfileString(” Boot”, “Print”, “LPT1”)); //写一整数pRegister->WriteProfileInt(” Boot”, “Hello”, nHello);//写一无符号整数pRegister->WriteProfileInt(” Boot”, “Sign”, nSign);//写一长整数pRegister->WriteProfileLong(” Boot”, “Good”, lgGood);//写单精度浮点数pRegister->WriteProfileFloat(” Boot”, ”LiPing”, fData);//写双精度浮点数pRegister->WriteProfileDouble(” Boot”, ”Line4”, dbData);//写布尔变量pRegister->WriteProfileString(“Boot”,”BootV”,((bBoolV)?”True”:”False”));//写字符串pRegister->WriteProfileString(” Boot”, “Print”, strPrintName); delete pRegister;} |
|
| 第8楼 bush | 发表于 2004-11-29 00:00 |
| 银牌会员 发帖 730 积分 2,165 | |
|
軟件看了: 他的表達不太清楚,開始我還以爲方括號是可選項呢!
我正在仿寫,過兩天發上來。 |
|
| 第9楼 bush | 发表于 2004-11-29 00:00 |
| 银牌会员 发帖 730 积分 2,165 | |
|
問兩個問題:
1、ini文件的内容是大小寫敏感的嗎? 2、其中可否允許空格?比如:
|
|
| 第10楼 郭恒 | 发表于 2004-12-01 00:00 |
| 中级用户 发帖 39 积分 225 | |
|
(1)一般来说,“键名”和“段名”是不区分大小的(2)注释语句一般是分号 (3)对于“键值”当然“内部”可以有“空格”(4)对于“键名”和“段名”能不能“内部”有“空格”,为保持与别的操作系统兼容,最好不要有“空格”, 我个人开发的接口就支持“空格”,微软公司的接口好像“段名”能够有“空格”。(5)对于“Bush"说的情况,是指“键”外部,当然可以,因为它是“手工编辑的“
|
|
| 第11楼 bush | 发表于 2004-12-03 00:00 |
| 银牌会员 发帖 730 积分 2,165 | |
|
/*http://www.sjlongtai.com/up/2004-12-3-510375.zip*/
#include <stdio.h> #include <stdlib.h> #include <io.h>/* ============================================= =============================================== */int main(int argc, char* argv) { /*~~~~~~~~~~~~~~~~*/ FILE* fp = 0; FILE* fout = 0; char* buf; int i, j; char found = 'n'; /*~~~~~~~~~~~~~~~~*/ if(argc < 3 || argc > 5) { printf("iniEdit by bush@CDU\n\ Usage:Add/Change/Remove/Read entries in INI files\n\ Add or Change:\n\tiniEdit filename section item value\n\ Remove:\n\tiniEdit filename section item /r\n\ \tiniEdit filename section /r\n\ Read:\n\tiniEdit filename section item\n\ \t(generates a SET statement to STDOUT)\n\ \tiniEdit filename section\n\ \t(generates SET statements for all items in section)\n" ;return 0; } if(!(fp = fopen(argv, "r"))) { printf("Cannot open inifile!\n"); return 1; } if(!(buf = (char*) malloc(1024))) { printf(" not enough memory!\n"); return 2; } if(argc == 3 || argc == 4 && (argv != '/' || argv != 'r' ) /*read*/{ while(buf = fgets(buf, 1024, fp)) { for(i = 0; buf == ' ' || buf == '\t'; i++); if(buf == ';' || buf == '\n' continue;if(buf == ' for(j = 0; argv && argv == buf; j++); if(argv || buf != ']' continue; for(; buf = fgets(buf, 1024, fp)![]() { for(i = 0; buf == ' ' || buf == '\t'; i++); if(buf == ';' || buf == '\n' continue;if(buf == 'break; if(argc > 3) { for(j = 0; argv && argv == buf; j++); if(argv || buf != '=' continue;printf("%s%s", argv, &buf); break; } else { printf("%s", &buf); } } free(buf); fclose(fp); return 0; } } return 8; } else /*add or change*/ { if(!(fout = fopen("tempini.dat", "w"))) { printf("Open file error!\n"); free(buf); return 1; } while(buf = fgets(buf, 1024, fp)) { for(i = 0; buf == ' ' || buf == '\t'; i++); if(buf == '\n' continue;if(buf == ';' ![]() { fputs(&buf, fout); continue; } if(buf == ' for(j = 0; argv && argv == buf; j++); if(argv || buf != ']' ![]() { fputs(&buf, fout); continue; } found = 'y'; /*found the section*/ if(argc == 4) /* remove section */ { for(; buf = fgets(buf, 1024, fp) ![]() { for(i = 0; buf == ' ' || buf == 't'; i++); if(buf == '\n' continue;if(buf == ' , fout); break; } } } else { fputs(&buf, fout); for(; buf = fgets(buf, 1024, fp) ![]() { for(i = 0; buf == ' ' || buf == '\t'; i++); if(buf == '\n' continue;if(buf == ';' ![]() { fputs(&buf, fout); continue; } if(buf == '/* whether insert new value */ { if(argv != '/' && argv != 'r' ![]() fprintf(fout, "%s=%s\n", argv, argv); fputs(&buf, fout); break; } for(j = 0; argv && argv == buf; j++); if(argv || buf != '=' ![]() { fputs(&buf, fout); continue; } if(argv != '/' && argv != 'r' ![]() fprintf(fout, "%s=%s\n", argv, argv); /*chage*/ break; } if(!buf && argv != '/' && argv != 'r' ![]() fprintf(fout, "%s=%s", argv, argv); } if(!buf) break; while(buf = fgets(buf, 1024, fp)) fputs(buf, fout); break; } else { fputs(&buf, fout); continue; } } if(found == 'n' /*add new section and value*/{ fprintf(fout, "\n", argv); fprintf(fout, "%s=%s", argv, argv); } fclose(fp); fclose(fout); free(buf); if(unlink(argv)) { printf("the inifile is read-only\n"); return 4; } rename("tempini.dat", argv); } return 0; } |
|
| 第12楼 bush | 发表于 2004-12-03 00:00 |
| 银牌会员 发帖 730 积分 2,165 | |
|
下載測試我的程序:http://www.sjlongtai.com/up/2004-12-3-510375.zip 大小10KB寫這個程序簡直腦子都要坏掉了~現在是這樣:
文件名參數要帶擴展名;……可能還有些問題,如有BUG請大家提出, 謝~ |
|
| 第13楼 郭恒 | 发表于 2004-12-11 00:00 |
| 中级用户 发帖 39 积分 225 | |
|
我给“BRUSH“的一点建议! “BRUSH“的程序不错,很有独见之处,只可惜目前只是雏形,离适用性还有一段时间。根据我的经验,完整的设计思想应该是这样: 1:打开并分析文件,将所有的“段名”和其在文件中“位置”放入一个“单/双向链表中” 2:建立“写”缓冲区,由--“段名”、“键名”、“键值”、“键值类型”四种要素组成。 该缓冲区,既可以是“数组”也可以是“链表”,建议用“数组”。它的作用是“写键值” 写入时,不直接写在文件中,而是写在该缓冲区中。 3:“读键值”。首先从“写”缓冲区中寻找对应的“段名”和“键名”,若找到,则直接 返回结果;若没有找到,则根据第一条所提到的“段名”链表中找对应的“段名”,若没有 找到对应的“段名”,则返回默认值;若找到对应的“段名”,则定位到其文件“位置”, 然后循环读“下一行”,分解出“键名”、“键值”和“注释”(判断是否是键名=键值表达,不是的话继续), 判断“键名”与指定的“键名”是否相符,"是",则返回结果,"不是",则继续循环下一行,直到下一个 “段名”或“文件结束”时止。 3:“写键值”。置文件“脏”标志,再在“写”缓冲区中寻找对应的“段名”和“键名”,若找到,则直接 更新结果;若没有找到,找一空位置,将“信息”写入缓冲区中,若缓冲区已满,则“更新 整个文件”,重新建立“段名”链表,清空“写缓冲区”,并清文件“脏”标志。。 4:关闭文件。若文件“脏”,则更新文件后关闭文件;否则直接关闭“文件”注意问题:由于DOS只有640K的常规内存,故装入并分析文件时,没有将文件内容分析成“二叉树”的形式。如果是WINDOWS版本,可以这样做。
|
|
| 第14楼 bush | 发表于 2004-12-13 00:00 |
| 银牌会员 发帖 730 积分 2,165 | |
|
郭恒之建议很好呀!不过有一点我没想明白的是:
将所有的“段名”和其在文件中“位置”放入一个“单/双向链表中 而“段名”、“键名”是树型的,且要处理“注释”(不能舍弃) 这个链表模型如何建,还须要考虑…… |
|
| 第15楼 郭恒 | 发表于 2004-12-14 00:00 |
| 中级用户 发帖 39 积分 225 | |
|
回答BUSH: 《1》 “段名链表”只纪录两个域,不包括“键名”信息 (1)段的名字 (2)段的32位文件指针位置 《2》 在初期开发时,可用“数组”代替“链表”,以便简化程序。 《3》“读键值”。 (1)从“写缓冲区”中“读”取键值。 (2)根据“段链表/数组”,定位对应的段在文件中的位置,分析每一行,直到不再分析下一行。 《4》“写键值”。 (1)写到“写缓冲区”,并置文件“脏”标志。 (2若“缓冲区”满,则更新文件、重新分析“段名链表/数组”、清空“缓冲区”。 《6》关闭文件。 (1)若文件不“脏”,则直接关闭 (2)若文件“脏”,更新文件。
|
|
| 1 2 下一页 |
|
[ 联系联盟系统管理团队 -
中国DOS联盟 -
标准版 ] Sponsored by ifanr Inc | © 2001–2023 |