中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS开发编程 & 发展交流 (开发室) » 怎样用C编写读取INI的配置文件?
« [1] [2] »
作者:
标题: 怎样用C编写读取INI的配置文件? 上一主题 | 下一主题
profree
中级用户




积分 478
发帖 132
注册 2003-7-2
状态 离线
『楼 主』:  怎样用C编写读取INI的配置文件?

怎样用C编写读取INI的配置文件?

2004-11-14 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
qb45
高级用户




积分 677
发帖 194
注册 2003-9-13
状态 离线
『第 2 楼』:  

INI的配置文件实际上是文本文件,不知道c语言有哪几种打开方式,用qb的话用OPEN "TEST.INI " FOR INPUT AS #1如果你想用2进制方式打开也行,也是可以读出的OPEN "TEST.INI " FOR BINARY AS #1



我(QB45)的照片与简历
http://www.programfan.com/club/showbbs.asp?id=197280
2004-11-15 00:00
查看资料  发送邮件  发短消息 网志  OICQ (406930019)  编辑帖子  回复  引用回复
profree
中级用户




积分 478
发帖 132
注册 2003-7-2
状态 离线
『第 3 楼』:  

对,是文本文件,但需要作一些判断,键名是多少,键值是多少,我找到一个外国人编写的DOS下inifile的文件,非常不错,但就是没有源代码呀,

2004-11-15 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
qb45
高级用户




积分 677
发帖 194
注册 2003-9-13
状态 离线
『第 4 楼』:  

可惜偶不懂c!



我(QB45)的照片与简历
http://www.programfan.com/club/showbbs.asp?id=197280
2004-11-15 00:00
查看资料  发送邮件  发短消息 网志  OICQ (406930019)  编辑帖子  回复  引用回复
bush
银牌会员




积分 2165
发帖 730
注册 2004-4-21
状态 离线
『第 5 楼』:  

把那個外國人的程序發來試試,大家一起分析

2004-11-19 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
profree
中级用户




积分 478
发帖 132
注册 2003-7-2
状态 离线
『第 6 楼』:  

打开附件

只是一个可执行文件

[此贴子已经被作者于2004-11-20 17:54:11编辑过]




2004-11-20 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
郭恒
中级用户




积分 225
发帖 39
注册 2004-10-6
状态 离线
『第 7 楼』:  

可在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[256];_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;}

2004-11-24 00:00
查看资料  发送邮件  访问主页  发短消息 网志   编辑帖子  回复  引用回复
bush
银牌会员




积分 2165
发帖 730
注册 2004-4-21
状态 离线
『第 8 楼』:  

軟件看了: 他的表達不太清楚,開始我還以爲方括號是可選項呢!
我正在仿寫,過兩天發上來。

2004-11-29 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
bush
银牌会员




积分 2165
发帖 730
注册 2004-4-21
状态 离线
『第 9 楼』:  

問兩個問題:
1、ini文件的内容是大小寫敏感的嗎?
2、其中可否允許空格?比如:

  Quote:
[s1]
   a=1
b=2
      [s2]
a=1
[    s3     ]
c    =  4



2004-11-29 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
郭恒
中级用户




积分 225
发帖 39
注册 2004-10-6
状态 离线
『第 10 楼』:  

(1)一般来说,“键名”和“段名”是不区分大小的(2)注释语句一般是分号 (3)对于“键值”当然“内部”可以有“空格”(4)对于“键名”和“段名”能不能“内部”有“空格”,为保持与别的操作系统兼容,最好不要有“空格”,         我个人开发的接口就支持“空格”,微软公司的接口好像“段名”能够有“空格”。(5)对于“Bush"说的情况,是指“键”外部,当然可以,因为它是“手工编辑的“

2004-12-1 00:00
查看资料  发送邮件  访问主页  发短消息 网志   编辑帖子  回复  引用回复
bush
银牌会员




积分 2165
发帖 730
注册 2004-4-21
状态 离线
『第 11 楼』:  

[url]/*http://www.sjlongtai.com/up/2004-12-3-510375.zip*/[/url]
#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[1], "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[3][0] != '/' || argv[3][1] != 'r')) /*read*/
{
  while(buf = fgets(buf, 1024, fp))
  {
   for(i = 0; buf == ' ' || buf == '\t'; i++);
   if(buf == ';' || buf == '\n') continue;
   if(buf[i++] == '[')
   {
    for(j = 0; argv[2][j] && argv[2][j] == buf[i + j]; j++);
    if(argv[2][j] || buf[i + j] != ']') 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[3][j] && argv[3][j] == buf[i + j]; j++);
      if(argv[3][j] || buf[i + j] != '=') continue;
      printf("%s%s", argv[3], &buf[i + j]);
      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[i++] == '[')
   {
    for(j = 0; argv[2][j] && argv[2][j] == buf[i + j]; j++);
    if(argv[2][j] || buf[i + j] != ']')
    {
     fputs(&buf[i - 1], 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 == '[')
      {
       fputs(&buf, fout);
       break;
      }
     }
    }
    else
    {
     fputs(&buf[i - 1], 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[4][0] != '/' && argv[4][1] != 'r')
        fprintf(fout, "%s=%s\n", argv[3], argv[4]);
       fputs(&buf, fout);
       break;
      }      for(j = 0; argv[3][j] && argv[3][j] == buf[i + j]; j++);
      if(argv[3][j] || buf[i + j] != '=')
      {
       fputs(&buf, fout);
       continue;
      }      if(argv[4][0] != '/' && argv[4][1] != 'r')
       fprintf(fout, "%s=%s\n", argv[3], argv[4]); /*chage*/
      break;
     }     if(!buf && argv[4][0] != '/' && argv[4][1] != 'r')
      fprintf(fout, "%s=%s", argv[3], argv[4]);
    }    if(!buf) break;
    while(buf = fgets(buf, 1024, fp)) fputs(buf, fout);
    break;
   }
   else
   {
    fputs(&buf[i - 1], fout);
    continue;
   }
  }  if(found == 'n')  /*add new section and value*/
  {
   fprintf(fout, "[%s]\n", argv[2]);
   fprintf(fout, "%s=%s", argv[3], argv[4]);
  }  fclose(fp);
  fclose(fout);
  free(buf);
  if(unlink(argv[1]))
  {
   printf("the inifile is read-only\n");
   return 4;
  }  rename("tempini.dat", argv[1]);
} return 0;
}


2004-12-3 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
bush
银牌会员




积分 2165
发帖 730
注册 2004-4-21
状态 离线
『第 12 楼』:  

下載測試我的程序:http://www.sjlongtai.com/up/2004-12-3-510375.zip 大小10KB寫這個程序簡直腦子都要坏掉了~現在是這樣:

  Quote:
文件名參數要帶擴展名;
段名、鍵名大小敏感;
段名可有空隔,如:[ab cd];
輸入端名無需方括號,但中間有空隔的必須用雙引號:"ab cd";
支持前端空格,如:
       [s1]
t1=2
                     t2=other
可加入新的段;

……可能還有些問題,如有BUG請大家提出,   謝~

2004-12-3 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
郭恒
中级用户




积分 225
发帖 39
注册 2004-10-6
状态 离线
『第 13 楼』:  

    我给“BRUSH“的一点建议!  “BRUSH“的程序不错,很有独见之处,只可惜目前只是雏形,离适用性还有一段时间。根据我的经验,完整的设计思想应该是这样:    1:打开并分析文件,将所有的“段名”和其在文件中“位置”放入一个“单/双向链表中”    2:建立“写”缓冲区,由--“段名”、“键名”、“键值”、“键值类型”四种要素组成。        该缓冲区,既可以是“数组”也可以是“链表”,建议用“数组”。它的作用是“写键值”        写入时,不直接写在文件中,而是写在该缓冲区中。   3:“读键值”。首先从“写”缓冲区中寻找对应的“段名”和“键名”,若找到,则直接         返回结果;若没有找到,则根据第一条所提到的“段名”链表中找对应的“段名”,若没有        找到对应的“段名”,则返回默认值;若找到对应的“段名”,则定位到其文件“位置”,        然后循环读“下一行”,分解出“键名”、“键值”和“注释”(判断是否是键名=键值表达,不是的话继续),       判断“键名”与指定的“键名”是否相符,"是",则返回结果,"不是",则继续循环下一行,直到下一个       “段名”或“文件结束”时止。   3:“写键值”。置文件“脏”标志,再在“写”缓冲区中寻找对应的“段名”和“键名”,若找到,则直接         更新结果;若没有找到,找一空位置,将“信息”写入缓冲区中,若缓冲区已满,则“更新         整个文件”,重新建立“段名”链表,清空“写缓冲区”,并清文件“脏”标志。。    4:关闭文件。若文件“脏”,则更新文件后关闭文件;否则直接关闭“文件”注意问题:由于DOS只有640K的常规内存,故装入并分析文件时,没有将文件内容分析成“二叉树”的形式。如果是WINDOWS版本,可以这样做。

2004-12-11 00:00
查看资料  发送邮件  访问主页  发短消息 网志   编辑帖子  回复  引用回复
bush
银牌会员




积分 2165
发帖 730
注册 2004-4-21
状态 离线
『第 14 楼』:  

郭恒之建议很好呀!不过有一点我没想明白的是:

  Quote:
将所有的“段名”和其在文件中“位置”放入一个“单/双向链表中

而“段名”、“键名”是树型的,且要处理“注释”(不能舍弃)
这个链表模型如何建,还须要考虑……
[em13]

2004-12-13 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
郭恒
中级用户




积分 225
发帖 39
注册 2004-10-6
状态 离线
『第 15 楼』:  

回答BUSH:    《1》 “段名链表”只纪录两个域,不包括“键名”信息          (1)段的名字           (2)段的32位文件指针位置   《2》 在初期开发时,可用“数组”代替“链表”,以便简化程序。  《3》“读键值”。         (1)从“写缓冲区”中“读”取键值。          (2)根据“段链表/数组”,定位对应的段在文件中的位置,分析每一行,直到不再分析下一行。  《4》“写键值”。          (1)写到“写缓冲区”,并置文件“脏”标志。           (2若“缓冲区”满,则更新文件、重新分析“段名链表/数组”、清空“缓冲区”。   《6》关闭文件。         (1)若文件不“脏”,则直接关闭          (2)若文件“脏”,更新文件。

2004-12-14 00:00
查看资料  发送邮件  访问主页  发短消息 网志   编辑帖子  回复  引用回复
« [1] [2] »
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: