【发布时间】:2019-12-17 09:38:28
【问题描述】:
我正在读取和保存格式化文件中的字符串,但由于某种原因,我发现 sscanf() 更改了 testa_e->ident 的内容。
我放了一些printf,发现问题出现在sscanf()之后;我还通过打印检查了temp2、temp5 和testa_e 的地址,但它们是不同的。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define string 30
#define line 100
typedef const char *identifier;
struct nodo_id {
identifier ident;
struct nodo_id *next;
};
typedef struct nodo_id nodo_id;
nodo_id *testa_e = NULL;
void addent(const char *id_ent) {
if (testa_e == NULL) {
testa_e = malloc(sizeof(nodo_id));
testa_e->ident = id_ent;
testa_e->next = NULL;
} else {
nodo_id *curs = testa_e;
while (curs != NULL) {
curs = curs->next;
}
curs = malloc(sizeof(nodo_id));
curs->ident = id_ent;
curs->next = NULL;
}
}
int main() {
char temp[line];
char temp2[string];
char temp5[string];
fgets(temp, line, stdin);
while (strncmp(temp, "end", 3) != 0) {
if (strncmp(temp, "addent", 6) == 0) {
if (testa_e != NULL)
printf("\nbefore sscanf: %s\n", testa_e->ident);
sscanf(temp, "%s %s", temp5, temp2);
if (testa_e != NULL)
printf("\nafter sscanf: %s\n", testa_e->ident);
addent(temp2);
}
fgets(temp, line, stdin);
}
}
这里的代码重现了完全相同的问题;启动后写addent firstword和addent secondword在终端和sscanf附近它应该告诉你testa_e->ident内容已经改变,我想知道为什么以及如何解决这个问题,因为我真的不知道。 ..
【问题讨论】:
-
这不是问题,但看起来你的
addent函数不能添加多个。遍历列表直到curs为NULL的循环等效于nodo_id* curs=NULL;。 -
你能展示完整的会话,包括你的输入和所有输出吗?
-
我的电脑现在死机了,我正在打电话我收到费用后会尽快处理,“完整会话”是指我的完整代码吗?
-
我不知道你输入的字符串有多大,但是
scanf的众多问题之一是不方便正确防止缓冲区溢出。但是您可能想使用sscanf(temp,"%29s %29s",temp5,temp2),它应该避免溢出temp5和temp2。 (如果您更改数组的大小,即如果您更改string,请记住更改%s指令中的数字。)
标签: c list scanf undefined-behavior singly-linked-list