我是C编程的初学者,我正在尝试创建一个算法来查找第一个和跟随给定语法的集合将在.txt文件中。
输入语法如下所示:
S-abA|e|bhG|AKX
A-Kb|d
K-j|c|e
X-p
到目前为止,我只是试图定义我将用于查找这些集合的结构(以及我遇到的问题)。
我使用列表向量,其中每个列表将包含我的语法的RHS值,并且向量中的每个位置(由输入文件中的规则或行数定义)将是指针到列表。 下面的函数编译并且几乎有效。正在正确阅读作品和变量" producao"工作正常,我已经尝试将其打印出来并正确地获得每个值,但是当我将这些值添加到列表中时,当我打印整个列表时,我最终得到的是:
我遇到问题的功能发布在下面:
criaListaRegras()
{
lista *regras;
regras = cria_lista(); // initialize list pointing to null
lista **vetor; // declare the vector of list pointers
vetor = malloc(sizeof(lista)*numLinhas);
int i = 0;
int numLinha = 0;
char producao[10]; // Each production in the RHS will have at most 9 characters and will be added to this variable, one at a time.
FILE *entrada;
entrada = fopen("entrada.txt", "r"); // input file
fseek(entrada, 2, SEEK_SET); // seek to RHS of the rule. (S-ab|AbB), makes fp go to 'a'.
char linha; // Will be used to parse the input
while ((linha = getc(entrada)) != EOF){
if (linha == '\n'){ // checks if a rule has ended, so that we add end of string to production and append that into the list.
producao[i] = '\0';
inserir(regras, producao); // append production (producao) into the list (regras).
imprimir(regras); // should print all values inside "regras" but only print the last value added * "number of productions found so far".
vetor[numLinha] = regras; // should assign a list into its position in the pre-defined vector of lists at position "numLinha".
i = 0; // resets string position counter to 0 so we can reuse it for next production.
numLinha++; // increment line/rule counter.
fseek(entrada, 2, SEEK_CUR);
}
if (linha == '|'){ // our production delim is '|', so if we find it, means a production has ended and we should add it into the list.
producao[i] = '\0';
inserir(regras, producao);
i = 0;
}
if(linha != '|' && linha != '\n'){ // this means the current char (linha) is part of some RHS production, so we should concatenate it into the variable producao on position 'i' and increment 'i'.
producao[i] = linha;
i++;
}
}
}
criaListaRegras()中使用的其他函数对于测试值工作正常,可以在下面找到:
lista *cria_lista()
{
lista *novo = (lista*)malloc(sizeof(lista));
novo->next = NULL;
return novo;
}
void imprimir(lista *original)
{
lista * aux = original->next;
while(aux!= NULL){
printf("%s\n", aux->nome);
aux=aux->next;
}
}
void inserir(lista *original, char *nome)
{
lista *base = original;
lista *aux = original->next;
lista *novo;
while(aux!= NULL){
aux=aux->next;
base=base->next;
}
novo=(lista*)malloc(sizeof(lista));
novo->nome = nome;
novo->next = aux;
base->next = novo;
}
如果有人能指出我在那里做错了什么,我会很高兴。
答案 0 :(得分:0)
查看提供源代码并使用criaListaRegras()
函数构建完整示例,我检测到多个错误,并且可能会创建观察到的输出。
假设1 - 如何声明结构lista
。
在解析源代码时,lista
有2个属性next
(用于链表机制)和nome
来存储加载的“producao”(char producao [10]; )。
typedef struct slista {
char *nome; // or char nome[10];
struct slista *next;
} lista;
问题1 - 附加到lista
结构,函数inserir()
不存储char *nome
参数的内容,只存储指针。
novo=(lista*)malloc(sizeof(lista));
novo->nome = nome; // ERROR storing the pointer
novo->next = aux;
base->next = novo;
通过存储char *nome
参数的指针(它是局部变量char producao[10];
的指针),每个节点lista
将具有指针值,并且在使用{{1}时},imprimir()
将指向最后一个条目(对于aux->nome
,它是"S-abA|e|bhG|AKX"
,...)。
解决方案1.1 - 如果"AKX"
的属性声明为lista
,则需要分配字符串并复制内容。
最简单的解决方案是使用能够分配和复制的
char *nome;
字符串。
strdup()
解决方案1.2 - 如果novo=(lista*)malloc(sizeof(lista));
novo->nome = strdup(nome); // allocate and copy
novo->next = aux;
base->next = novo;
的属性声明为lista
,则只需要复制字符串。
输入(来自
char nome[10];
)仅限于(10-1)char producao[10];
和 可以使用函数char
轻松复制。
strcpy()
其他检测到的问题:
1 - 分配novo=(lista*)malloc(sizeof(lista));
strcpy(novo->nome,nome); // copy from nome to novo->nome
novo->next = aux;
base->next = novo;
vetor
。
变量
lista
是lista **vetor;
的数组而不是lista *
。
lista
而不是
lista **vetor; // declare the vector of list pointers
vetor = (lista **)malloc(sizeof(lista *)*numLinhas);
2 - 在使用lista **vetor; // declare the vector of list pointers
vetor = (lista **)malloc(sizeof(lista)*numLinhas);
之后和阅读数据之前检查FILE *entrada;
值。
3 - 在fopen()
中存储完整的lista *regras
(vetor[numLinha] = regras;
)后,您需要创建一个新的。{/ p>
再次致电
vetor
regras = cria_lista();