下面是本人写的临时测试代码,有时单步运行看其他变量都没问题,唯独keyName有时能一个个正常写入,有时读到第二个section时(开始存放这行了)结果会影响到keyName[0][?]中的数据,这是怎么回事?程序大部分运行时都不能按要求存入keyName中啊,只有偶尔没问题成功的。
目的是读取任何ini配置文件中的全部节名和对应的键名,存放方式是,例:节名[section 3]下的第三个键名 为name,则keyName[2][3]中存放键值。
目的是读取任何ini配置文件中的全部节名和对应的键名,存放方式是,例:节名[section 3]下的第三个键名 为name,则keyName[2][3]中存放键值。
#include "iostream"
#include "string"
#include "atltime.h"
#include "regex"
using namespace std;
class FileReadIn
{
public:
int sectionCount;//计数器
char* pSectionName[300];//保存找到的节名字符串的首地址
char* keyName[300][300];//保存全部路径(全部键值)
void findSectionPath()
{
char chSectionNames[2048] = { 0 }; //全部节名组成的字符数组
memset(pSectionName, 0, sizeof(pSectionName));
sectionCount = 0;
memset(keyName, 0, sizeof(keyName));
int j = 0;//j用来保存下一个节名字符串的首地址相对于当前i的位置偏移量
GetPrivateProfileSectionNames(chSectionNames, 2048, "E:\test.ini");
for (int i = 0; i < 2048; i++, j++)
{
if (chSectionNames[0] == "\0")//假如第一个字符就是0,则说明ini中一个节也没有
{
cout << "配置文件中一个节也没有" << endl;
break;
}
else if (chSectionNames[i] == "\0")
{
cout << "找到一个节名" << endl;//断点1
char* temp = &chSectionNames[i - j]; //找到一个0,则说明从这个字符往前,减掉j个偏移量,就是一个节名的首地址
cout << temp << endl; //把找到的显示出来
//找每个节名下的全部键
{
LPCSTR str1 = temp;
char keyNamesAll[300] = { 0 };
GetPrivateProfileString(str1, NULL, NULL, keyNamesAll, sizeof(keyNamesAll), "E:\test.ini");
int k = 0;
int keyCount = 0;
for (int i = 0; i < 2048; i++, k++)
{
if (keyNamesAll[0] == "\0")//假如第一个字符就是0,则说明ini中一个节也没有
{
cout << "当前节中一个键也没有" << endl;
}
else if (keyNamesAll[i] == "\0")
{
cout << "找到一个键名" << endl;//断点2
char* tempStr = &keyNamesAll[i - k];//找到一个0,则说明从这个字符往前,减掉j个偏移量,就是一个节名的首地址
cout << tempStr << endl; //把找到的显示出来
keyName[sectionCount][keyCount] = tempStr;
k = -1;
keyCount++;
if (keyNamesAll[i + 1] == 0)//当两个相邻的字符都是0时,则全部的节名都已找到,循环终止
{
break;
}
}
}
}//已找完该节名下的键名
pSectionName[sectionCount] = temp;
j = -1;
sectionCount++;
if (chSectionNames[i + 1] == 0)//当两个相邻的字符都是0时,则全部的节名都已找到,循环终止
{
break;
}
}
}
cout << "as" << endl;//断点3
}
};
int main()
{
FileReadIn A;
A.findSectionPath();
cout << "ffffgg"<< endl;//断点
system("PAUSE");
return 0;
}
解决方案
20
首先回答你的问题,为什么keyName值会被覆盖?你的keyName数组里存的是字符串地址,而这个地址来源于你定义的一个局部数组char keyNamesAll[300] = { 0 },
在你每次调用GetPrivateProfileString(str1, NULL, NULL, keyNamesAll, sizeof(keyNamesAll), “C:\test.ini”)函数时,这个
数组中存放的字符都会发生变化,当ini文件解析结束后,这个数组中存放的就是最后一个section中的全部keyName,这就是为什么当解析第2个section时,keyName[0][*]
变化的原因。原因是keyNamesAll中存放的字符已经变化了,而keyName中存放的只是keyNamesAll某个offset的地址,keyName内存放的值当然随着keyNamesAll的
变化而变化了。
其次,你这样的写法也是不对的,局部变量超出其作用域,就不应该被引用了,而在你的程序中使用类的成员变量存储了局部变量的地址,这无疑超出了局部变量的作用域。
建议你可以使用vector, map
在你每次调用GetPrivateProfileString(str1, NULL, NULL, keyNamesAll, sizeof(keyNamesAll), “C:\test.ini”)函数时,这个
数组中存放的字符都会发生变化,当ini文件解析结束后,这个数组中存放的就是最后一个section中的全部keyName,这就是为什么当解析第2个section时,keyName[0][*]
变化的原因。原因是keyNamesAll中存放的字符已经变化了,而keyName中存放的只是keyNamesAll某个offset的地址,keyName内存放的值当然随着keyNamesAll的
变化而变化了。
其次,你这样的写法也是不对的,局部变量超出其作用域,就不应该被引用了,而在你的程序中使用类的成员变量存储了局部变量的地址,这无疑超出了局部变量的作用域。
建议你可以使用vector, map
#include "iostream"
#include "string"
#include "atltime.h"
#include "regex"
#include <vector>
#include <map>
using namespace std;
class FileReadIn
{
public:
int sectionCount;//计数器
vector<string> sectionNames;//保存找到的节名字符串的首地址
map<string, vector<string> > sectionNameToKeys;//保存全部路径(全部键值)
void findSectionPath()
{
char chSectionNames[2048] = { 0 }; //全部节名组成的字符数组
char keyNamesAll[300] = { 0 };
int j = 0;//j用来保存下一个节名字符串的首地址相对于当前i的位置偏移量
GetPrivateProfileSectionNames(chSectionNames, 2048, "C:\TestSetup_XSIM7.ini");
for (int i = 0; i < 2048; i++, j++)
{
if (chSectionNames[0] == "\0")//假如第一个字符就是0,则说明ini中一个节也没有
{
cout << "配置文件中一个节也没有" << endl;
break;
}
else if (chSectionNames[i] == "\0")
{
cout << "找到一个节名" << endl;//断点1
char* temp = &chSectionNames[i - j]; //找到一个0,则说明从这个字符往前,减掉j个偏移量,就是一个节名的首地址
cout << temp << endl; //把找到的显示出来
vector<string> keys;
//找每个节名下的全部键
{
LPCSTR str1 = temp;
GetPrivateProfileString(str1, NULL, NULL, keyNamesAll, sizeof(keyNamesAll), "C:\TestSetup_XSIM7.ini");
int k = 0;
int keyCount = 0;
for (int i = 0; i < 2048; i++, k++)
{
if (keyNamesAll[0] == "\0")//假如第一个字符就是0,则说明ini中一个节也没有
{
cout << "当前节中一个键也没有" << endl;
}
else if (keyNamesAll[i] == "\0")
{
cout << "找到一个键名" << endl;//断点2
char* tempStr = &keyNamesAll[i - k];//找到一个0,则说明从这个字符往前,减掉j个偏移量,就是一个节名的首地址
cout << tempStr << endl; //把找到的显示出来
keys.push_back(string(tempStr));
k = -1;
keyCount++;
if (keyNamesAll[i + 1] == 0)//当两个相邻的字符都是0时,则全部的节名都已找到,循环终止
{
break;
}
}
}
}//已找完该节名下的键名
sectionNames.push_back(string(temp));
sectionNameToKeys[string(temp)] = keys;
j = -1;
sectionCount++;
if (chSectionNames[i + 1] == 0)//当两个相邻的字符都是0时,则全部的节名都已找到,循环终止
{
break;
}
}
}
cout << "as" << endl;//断点3
}
};
int main()
{
FileReadIn A;
A.findSectionPath();
cout << "ffffgg"<< endl;//断点
system("PAUSE");
return 0;
}