c - C - 结构中的结构数组在 dfa 程序中返回意外结果
问题描述
我正在尝试制作一个基于用户输入创建 dfa 的程序。每个节点和转换必须是一个结构,而 dfa 也是一个结构。dfa 结构包含一个节点结构数组和一个转换结构的链表。这是我到目前为止所拥有的:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_STATES 25
#define TRUE 1
#define FALSE 0
#define MAXCHAR 256
/* struct for a state of the DFA */
typedef struct state {
char *id;
int isInitial;
int isFinal;
} STATE_T;
/* struct for a transition of the DFA*/
typedef struct transition {
STATE_T *startState;
char condition;
STATE_T *endState;
struct transistion *next;
} TRANSITION_T;
/* struct for the DFA */
typedef struct automaton {
STATE_T state[MAX_STATES];
TRANSITION_T *transition;
} AUTOMATON_T;
/* main function reads initial user inputs to build dfa */
int main() {
AUTOMATON_T dfa;
STATE_T stateA;
TRANSITION_T *trans;
文本文件的第一行是逗号分隔的节点/状态,例如:“a,b,c”。但是,当我将每个节点作为状态 id 分配到 dfa 结构中时,最终状态将分配给每个状态的 id。以下代码中的 for 语句会打印 0c 1c 2c,而我希望是 0a 1b 2c。
FILE *fp = fopen(fileName, "r");
while (fgets(useIn, MAXCHAR, fp)) {
if (lineNum == 0) {
i = 0;
char *token = strtok(useIn, ",");
while (token != NULL) {
strcpy(stateId, token);
stateA.id = stateId;
dfa.state[i] = stateA;
i++;
token = strtok(NULL, ",");
}
stateAmt = i;
for (i = 0; i < stateAmt; i++) {
printf("%d", i);
printf("%s", dfa.state[i].id);
}
}
fclose(fp);
return 0;
}
为什么会这样?我是否错误地处理了状态数组?
解决方案
问题是这两行:
strcpy(stateId, token);
stateA.id = stateId;
在state
结构中,id
成员是指向可变字符串的指针。用于存储该字符串的内存只分配了一次,并且它的地址已存储在每个状态结构中。
为了让每个状态都有自己的 ID,您需要为每个状态分配一个新的 ID 缓冲区。您可以malloc
在运行时动态地执行此操作,或者您可以简单地将此缓冲区的存储包含为state
结构的一部分,如下所示:
typedef struct state {
char id[MAX_ID_LENGTH+1];
int isInitial;
int isFinal;
} STATE_T;
推荐阅读
- material-ui - React Material Design 选择和样式化组件
- python - NameError 错误 python3
- node.js - AWS Lambda 执行 15-20 秒以将遥测事件发送到 Azure Application Insights
- git - 沉默 git rebase --interactive 的“如何进行”消息
- perl - 迭代时无意中将键添加到哈希
- pandas - 如何根据熊猫中的条件获得加入?
- ios - 如何在 RXSwift 中重置 Observable 区间运算符?
- sequelize.js - 我得到的这个“defineCall 不是函数”错误是什么?
- product - 我设置了开发人员模式,当我创建产品时,它在前端商店软件中显示错误。
- excel - VBA Excel - 根据用户输入使用 xlFilterAllDatesInPeriod"Month"