tiantianzuiaixuexi 2020-05-17 11:22 采纳率: 25%
浏览 524

C++读取ini配置文件 ,windows下正常,linux下读取的数据不正确

自己写的一个读取ini配置文件

ini是这样的

[libevnet]
ServerAddress=0.0.0.0
ServerPost=80


[thread]
ServerThreadNum=5
SqlThreadNum=5

[Log]
LogLocation=../log


[Mysql]
SqlAdderss=127.0.0.1
SqlPost=3306

下面是代码

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cstring>


using namespace std;



//结构定义,这个是配置文件的定义
typedef struct
{
    char ItemName[50];
    char ItemContent[500];
}CConfItem, * LPCConfItem;

#define error_str(s,...)\
std::cout<<s<<",文件是: "<<__FILE__<<",行号是: "<<__LINE__<<std::endl;

std::map<std::string, std::vector<LPCConfItem>> m_ConfigItemList; //存储配置信息的列表
bool Load(const char* pconfName); //装载配置文件

bool Load(const char* pconfName)
{   
    FILE* fp;

#if _WIN32
    int err = fopen_s(&fp, pconfName,"r");
    if(err!=NULL) {
        error_str("读取配置文件失败")
        return false;
    }
#else 
    fp = fopen(pconfName,"r");
    if(fp==NULL){
        error_str("读取配置文件失败")
        return false;
    }
#endif

    char linebuf[501];                   //每一行的配置文件读出来放在这里
    char m_str[100];                     //Map的Ky
    std::vector<LPCConfItem> local_list; //存储配置信息的列表

    while(!feof(fp))    //检查文件是否结束 ,没有结束则条件成立
    {
        if (fgets(linebuf, 500, fp) == NULL) //从文件中读数据,每次读一行,一行最多不要超过500个字符 
            continue;

         if(linebuf[0]==0)
            continue;

            //处理注释
         if (*linebuf == ';' || *linebuf == ' ' || *linebuf == '#' || *linebuf == '\t' || *linebuf == '\n')
             continue;

lblprocstring:

    //屁股后边若有换行,回车,空格等都截取掉
    if(strlen(linebuf)>0)
    {
        if (linebuf[strlen(linebuf) - 1] == 10 || linebuf[strlen(linebuf) - 1] == 13 || linebuf[strlen(linebuf) - 1] == 32)
        {
            linebuf[strlen(linebuf) - 1] = 0;
            goto lblprocstring;
        }
    }
    //判断是否有找到[
    if(*linebuf == '['){
        if(!local_list.empty()){
            m_ConfigItemList.insert(pair<std::string,std::vector<LPCConfItem>>(m_str, local_list)); //插入
            local_list.clear();
        }   
        char* ptemp = strchr(linebuf,']');  //如果找到 '[' , 那么寻找 ']'
        if(ptemp==NULL){
            error_str("解析失败,没有找到 ']'")
            return false;
        }
#if _WIN32
        strncpy_s(m_str,sizeof(std::string),linebuf+1,(size_t)(ptemp-linebuf)-1);
#else
        strncpy(p_confitem->ItemName, linebuf, (size_t)(ptmp - linebuf));                //不带 '\0'
#endif
        continue;
    }

    //然后寻找=
    char*  ptmp = strchr(linebuf,'=');
    if(ptmp!=NULL){

        LPCConfItem p_confitem = new CConfItem;                                                                      //注意前边类型带LP,后边new这里的类型不带
        memset(p_confitem, 0, sizeof(CConfItem));                                                                    //指针滞空
#if _WIN32
        strncpy_s(p_confitem->ItemName,sizeof(p_confitem->ItemName),linebuf,(size_t)(ptmp-linebuf));                 //不带 '\0'
        strcpy_s(p_confitem->ItemContent, ptmp+1);                                                                   //带 '\0'
#else
        strncpy(p_confitem->ItemName,  linebuf, (size_t)(ptmp - linebuf));               //不带 '\0'
        strcpy(p_confitem->ItemContent, ptmp + 1);
#endif
        local_list.push_back(p_confitem);
    }
    }

    for(auto& a:m_ConfigItemList){

        cout<<a.first<<endl;
        for(auto& b:a.second)
        {
            cout<<b->ItemName <<endl;
            cout<<b->ItemContent<<endl;
        }
    }


    fclose(fp);
    return true;
}




int main()
{

    Load("fuck.ini");
    return 0;
}

下面是windwos读取的数据,

图片说明

下面是linux读取的数据

图片说明

还有如果我在windows中把 strncpy_s 替换成 memcpy_s 就会出现linux下的错误乱码,请问是为什么呢?
图片说明

  • 写回答

2条回答 默认 最新

  • threenewbee 2020-05-17 11:45
    关注

    windows和linux的换行符不同
    windows是\r\n
    linux是\r

    评论

报告相同问题?

悬赏问题

  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮