提问人:Poizone 提问时间:10/6/2023 最后编辑:chqrliePoizone 更新时间:10/6/2023 访问量:120
从文件读取日期到链表
Reading dates from file to linked list
问:
void readDataFromFile(President **h) {
FILE *fp = fopen("President.txt", "r");
if (fp == NULL) {
printf("Cannot open a file!\n");
return;
}
char buffer[MAX];
int rno, start_date, end_date;
char name[MAX];
while(fgets(buffer, MAX, fp) != NULL) {
// Reading data from line
if (sscanf(buffer, "%d %[^\n] %d-%d", &rno, name, &start_date, &end_date) != 4) {
printf("Error trying to read file!\n");
fclose(fp);
return;
}
// Creating of new node
President *newNode = (President*)malloc(sizeof(President));
if (newNode == NULL) {
printf("Memory error!\n");
fclose(fp);
return;
}
newNode->rno = rno;
strcpy(newNode->name, name);
newNode->start_date = start_date;
newNode->end_date = end_date;
newNode->next = NULL;
// Adding new node to list
if (*h == NULL) {
*h = newNode;
} else {
President* current = *h;
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
}
}
fclose(fp);
printf("Data is added to list!\n");
}
你好。我正在尝试从文件读取到链表,但我总是收到 if(sscanf) 的错误原因。我的代码有什么问题?我已经检查了几次文件中的文本,但没关系,但无论如何都无法阅读。我能得到一些帮助或一些有用的链接吗?如果您显示我可以在哪里阅读它,我准备自己管理它。
以下是输入文件中的三行示例行
1 President 2000-2004
2 President 1932-1957
3 President 2012-2016
答:
1赞
greg spears
10/6/2023
#1
我对您的代码的测试表明,正则表达式 %[^\n] 占用了该行的其余部分,没有为 start_date 和 end_date 变量留下任何内容,并且很可能是问题的根本原因。
我建议使用这个正则表达式: %[^ ] -- 它将在第一个空格处停止扫描:
sscanf(buffer, "%d %[^ ] %d-%d", &rno, name, &start_date, &end_date)
如果有 2 个名称用空格分隔,您可以这样做来解决这种情况——请记住,在此示例中,成功的 sscanf() 应返回 5:
sscanf(buffer, "%d %[^ ] %[^ ] %d-%d", &rno, fname, lname, &start_date, &end_date)
注意:@Weather Vane 非常友善地指出 %s 将代替 %[^ ]。是的,当然!(再次感谢)。
所有建议都已成功测试在具有此格式的数据文件上...显示版本 2 (名字 + 姓氏):
1 First Last 1933-1944
2 First Last 1944-1948
...
...
评论
1赞
Poizone
10/6/2023
1 总统 2004-2016 - 这是文件中包含的数据。
1赞
Weather Vane
10/6/2023
@Poizone那为什么你需要而不是名字呢?%[]
%s
1赞
Poizone
10/6/2023
@Kz2023 谢谢。现在没有错误,但无法写入链表。什么也没发生。可能是节点有问题。我会试着弄清楚的。
1赞
Fe2O3
10/6/2023
@Kz2023的优先级高于......可能想纠正你的问题,因为它目前没有做你认为它正在做的事情......==
=
if()
1赞
greg spears
10/6/2023
@Fe2O3 -- 谢谢!我很感激你。我匆匆忙忙...我知道我应该把这句话括起来。我不知道 = vs == ....再次感谢
1赞
chqrlie
10/6/2023
#2
给定输入行的格式,无法在发布的单个调用中解析它们。您应该使用 和 找到第一个和最后一个空格字符,然后用于转换数字并复制中间部分,即名称,其中可能嵌入了多个空格,例如:、。sscanf
strchr()
strrchr()
sscanf()
strcpy
Theodore Roosevelt
William H. Taft
#include <errno.h>
#include <stdio.h>
#include <string.h>
void readDataFromFile(President **h) {
FILE *fp = fopen("President.txt", "r");
if (fp == NULL) {
fprintf(stderr, "Cannot open file %s: %s\n",
"President.txt", strerror(errno));
return;
}
char buffer[MAX];
int rno, start_date, end_date, count = 0;
// Locating the last node if any
while (*h != NULL) {
h = &(*h)->next;
}
while (fgets(buffer, sizeof buffer, fp) != NULL) {
char *first = strchr(buffer, ' ');
char *last = strrchr(buffer, ' ');
if (!first || !last
|| (first += strspn(first, " ")) >= last
|| sscanf(buffer, "%d", &rno) != 1
|| sscanf(last, "%d-%d", &start_date, &end_date) != 2) {
fprintf(stderr, "invalid format: %s\n", buffer);
break;
}
while (last > buffer && last[-1] == ' ')
last--;
// Creating of new node
President *newNode = calloc(sizeof(*newNode), 1);
if (newNode == NULL) {
fprintf(sdterr, "Memory allocation error!\n");
break;
}
newNode->rno = rno;
// copy the name: use `snprintf` to prevent buffer overflow
snprintf(newNode->name, sizeof newNode->name,
"%.*s", (int)(last - first), first);
newNode->start_date = start_date;
newNode->end_date = end_date;
newNode->next = NULL;
// Appending new node to list
*h = newNode;
h = &(*h)->next;
count++;
}
fclose(fp);
printf("%d records added to list!\n", count);
}
上一个:Fread 功能是否阻塞?
下一个:无法理解 fgets 输出
评论