C语言,for循环创建链表节点,第二次循环的到链表malloc就直接触发断点
本帖最后由 kkkky 于 2020-1-27 17:11 编辑C语言,读取配置信息,以指定格式存放到链表中
for循环创建链表节点,第二次循环的到链表malloc(85行)就直接触发断点,附上代码各位大佬帮忙看看
已解决:不知道具体原因,只要是for循环创建节点同时给链表数据域的指针申请空间并拷贝数据。首次循环没有问题,第二次循环到了新节点malloc就会挂掉!
解决办法:改成两个for循环,一个for循环创建链节点并始化为0然后把各个节点连接起来,再写一个for循环创依次给每一个节点申请空间拷贝数据进去就无问题。
报错截图
https://attach.52pojie.cn//forum/202001/27/134617jev8evegfrjn3a6j.png?l
测试用配置文件截图
https://attach.52pojie.cn//forum/202001/27/135314dt84pwiwtw5y5xpy.png?l
头文件
```
#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct Info
{
char *key;
char *val;
struct Info *next;
};
#ifdef __cplusplus
extern "C" {
#endif
//获取有效行文件
int GetRow_Info(FILE *file);
//加载配置文件
void Loading_Info(const char *filePath, char ***fileData,int *line);
//解析文件
void Parse_Info(struct Info **info, char **fileData, int line);
//获得指定信息
char *Getinfo_Info(struct Info *info, char *dest);
//释放当前空间
void Destroy_Info(struct Info *info);
//判断当前行是否有效
int JudgRow_Info();
#ifdef __cplusplus
}
#endif
```
函数实现
```
#include"readwreit.h"
//获取有效行文件
int GetRow_Info(FILE *file)
{
if (NULL == file)
{
return 0;
}
int lines = 0;
char buf = {0};
while (fgets(buf, 1024, file) != NULL)
{
//调用JudgRow_Info函数 判断当前行是否有效
if (!JudgRow_Info(buf))
{
continue;
}
memset(buf, 0, 1024);
++lines;
}
//返回有效行数,重置指针到起始位置
rewind(file);
return lines;
}
//加载配置文件
void Loading_Info(const char *filePath, char ***fileData, int *line)
{
if (NULL == filePath)
{
return;
}
if (NULL == fileData)
{
return;
}
if (NULL == line)
{
return;
}
FILE *file = fopen(filePath,"r");
//调用GetRow_Info函数获取有效行
int lines = GetRow_Info(file);
int index = 0;
char buf = { 0 };
char **temp = malloc(sizeof(char *)*lines);
while (fgets(buf, 1024, file)!=NULL)
{
//调用JudgRow_Info函数 判断当前行是否有效
if (!JudgRow_Info(buf))
{
continue;
}
temp = malloc(sizeof(char *)*sizeof(buf) + 1);
strcpy(temp, buf);
++index;
memset(buf, 0, 1024);
}
//关闭文件,返回指存放有效数据的指针 有效行
fclose(file);
*fileData = temp;
*line = lines;
}
//解析文件
void Parse_Info(struct Info **info, char **fileData, int line)
{
if (NULL == fileData)
{
return;
}
if (NULL == info)
{
return;
}
int index = 0;
//创建头节点
struct Info *header = malloc(sizeof(struct Info));
memset(header, 0, sizeof(struct Info));
//定义一个辅助指针始终指向尾节点
struct Info *Rear = header;
for (int i = 0; i < line; ++i)
{
//创建新节点
struct Info *newnoed = malloc(sizeof(struct Info));
memset(newnoed, 0, sizeof(struct Info));
//新节点数据域的两个指针分配对应大小空间
char *pos = strchr(fileData, ':');
newnoed->key = malloc(pos - fileData+1);
newnoed->val = malloc(strlen(pos + 1) + 1);
//以指定格式把数据拷贝到链表中
strncpy(newnoed->key, fileData, pos - fileData);
strncpy(newnoed->val, pos + 1, strlen(pos + 1) - 1);
newnoed->next = NULL;
//新节点添加到链表中,辅助指针指向最后一个节点
Rear->next = newnoed;
Rear = Rear->next;
++index;
}
//释放解析文件空间
for (int i = 0; i < line; ++i)
{
free(fileData);
fileData = NULL;
}
free(fileData);
fileData = NULL;
*info = header;
}
//获取指定信息
char *Getinfo_Info(struct Info *info, char *dest)
{
if (NULL == info)
{
return 0;
}
if (NULL == dest)
{
return 0;
}
struct Info *pCurrent = info->next;
while (pCurrent != NULL)
{
if (strcmp(dest, pCurrent->key) == 0)
{
return pCurrent->val;
}
pCurrent = pCurrent->next;
}
return NULL;
}
//释放当前空间
void Destroy_Info(struct Info *info);
//判断当前行是否有效
int JudgRow_Info(const char *buf)
{
if (buf == '#' || buf == '\n' || strchr(buf, ':') == NULL)
{
return 0;
}
return 1;
}
``` {:1_926:}论坛的大佬们取哪里了 GetProfileString 可以直接读吧 tony666 发表于 2020-1-27 14:02
GetProfileString 可以直接读吧
刚入门 GetProfileString还没学过啊 kkkky 发表于 2020-1-27 14:44
刚入门 GetProfileString还没学过啊
抱歉,发错了 。。。。GetPrivateProfileString
https://docs.microsoft.com/zh-cn/windows/win32/api/winbase/nf-winbase-getprivateprofilestring
https://baike.baidu.com/item/GetPrivateProfileString/9642262?fr=aladdin 91行的后面加上
memset(newnoed->key, 0, pos - fileData + 1);
memset(newnoed->val, 0, strlen(pos + 1) + 1);
行不行?
其他好像没啥问题呀!
#include"readwreit.h"
//获取有效行文件
int GetRow_Info(FILE *file)
{
if (NULL == file)
{
return 0;
}
int lines = 0;
char buf = { 0 };
while (fgets(buf, 1024, file) != NULL)
{
//调用JudgRow_Info函数 判断当前行是否有效
if (!JudgRow_Info(buf))
{
continue;
}
memset(buf, 0, 1024);
++lines;
}
//返回有效行数,重置指针到起始位置
rewind(file);
return lines;
}
//加载配置文件
void Loading_Info(const char *filePath, char ***fileData, int *line)
{
if (NULL == filePath)
{
return;
}
if (NULL == fileData)
{
return;
}
if (NULL == line)
{
return;
}
FILE *file = fopen(filePath, "r");
//调用GetRow_Info函数获取有效行
int lines = GetRow_Info(file);
int index = 0;
char buf = { 0 };
char **temp = malloc(sizeof(char *)*lines);
while (fgets(buf, 1024, file) != NULL)
{
//调用JudgRow_Info函数 判断当前行是否有效
if (!JudgRow_Info(buf))
{
continue;
}
temp = malloc(sizeof(char *) * sizeof(buf) + 1);
strcpy(temp, buf);
++index;
memset(buf, 0, 1024);
}
//关闭文件,返回指存放有效数据的指针 有效行
fclose(file);
*fileData = temp;
*line = lines;
}
//解析文件
void Parse_Info(struct Info **info, char **fileData, int line)
{
if (NULL == fileData)
{
return;
}
if (NULL == info)
{
return;
}
int index = 0;
//创建头节点
struct Info *header = malloc(sizeof(struct Info));
memset(header, 0, sizeof(struct Info));
//定义一个辅助指针始终指向尾节点
struct Info *Rear = header;
for (int i = 0; i < line; ++i)
{
//创建新节点
struct Info *newnoed = malloc(sizeof(struct Info));
memset(newnoed, 0, sizeof(struct Info));
//新节点数据域的两个指针分配对应大小空间
char *pos = strchr(fileData, ':');
newnoed->key = malloc(pos - fileData + 1);
newnoed->val = malloc(strlen(pos + 1) + 1);
memset(newnoed->key, 0, pos - fileData + 1);
memset(newnoed->val, 0, strlen(pos + 1) + 1);
//以指定格式把数据拷贝到链表中
strncpy(newnoed->key, fileData, pos - fileData);
strncpy(newnoed->val, pos + 1, strlen(pos + 1) - 1);
newnoed->next = NULL;
//新节点添加到链表中,辅助指针指向最后一个节点
Rear->next = newnoed;
Rear = Rear->next;
++index;
}
//释放解析文件空间
for (int i = 0; i < line; ++i)
{
free(fileData);
fileData = NULL;
}
free(fileData);
fileData = NULL;
*info = header;
}
//获取指定信息
char *Getinfo_Info(struct Info *info, char *dest)
{
if (NULL == info)
{
return 0;
}
if (NULL == dest)
{
return 0;
}
struct Info *pCurrent = info->next;
while (pCurrent != NULL)
{
if (strcmp(dest, pCurrent->key) == 0)
{
return pCurrent->val;
}
pCurrent = pCurrent->next;
}
return NULL;
}
//释放当前空间
void Destroy_Info(struct Info *info, int size)
{
struct Info *temp = info->next;
while (temp->next != NULL)
{
if (temp->key != NULL)
{
free(temp->key);
temp->key = NULL;
}
if (temp->val != NULL)
{
free(temp->val);
temp->val = NULL;
}
temp = temp->next;
}
}
//判断当前行是否有效
int JudgRow_Info(const char *buf)
{
if (buf == '#' || buf == '\n' || strchr(buf, ':') == NULL)
{
return 0;
}
return 1;
}
int main()
{
char **fileData = NULL;
int line = 0;
Loading_Info("config.txt",
&fileData, &line);
struct Info *info = NULL;
Parse_Info(&info, fileData, line);
printf("key:%s\n", Getinfo_Info(info, "password"));
system("pause");
Destroy_Info(info, line);
return 0;
}
页:
[1]