【问题标题】:Reading text into a linked list using structs in C使用 C 中的结构将文本读入链表
【发布时间】:2015-06-29 05:33:41
【问题描述】:

我正在尝试使用 txt 文件中的结构创建链接列表。最初,我使用只有一行信息的 txt 文件对其进行测试。这段代码编译正确,但是当我运行它时,它返回“Line ...没有正确扫描”。顺便说一句,如果我删除返回这样一个值的 if 语句,我会得到完全的胡言乱语。我不知道为什么没有正确扫描该行,但是我觉得它可能与我试图扫描为字符串的两个术语中的连字符/加号有关。非常感谢您提供的任何帮助。

这是txt文件:

1 20959U 90103A   14091.58762725 -.00000015  00000-0  00000+0 0  3197

这是 tester.c 文件:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct noradData {
    // line one
    int                lineNum;
    char             * satNum;
    char             * intDesig;
    float              epoch;
    float              firstTimeDeriv;
    char             * secondTimeDeriv;
    char             * drag;
    int                zero;
    int                set;
    struct noradData * next;
} Data; 

Data * first = NULL, * last = NULL;

int main() {
    char line[80], secondTimeDeriv[7], drag[7], satNum[6], intDesig[6];
    int lineNum, zero, set; 
    float epoch, firstTimeDeriv;

    FILE * fIn;
    Data * node;

    fIn = fopen("data1.txt", "r");
    if (fIn == NULL) {
        printf("Cannot open file\n");
        return 1;
    }

    while (fgets(line, sizeof(line), fIn) != NULL) {
        // Check line for various problems (too short, too long).
        if (line[0] == '\0') {
            printf ("Line too short\n");
            return 1;
        }

        if (line[strlen (line)-1] != '\n') {
            printf ("Line starting with '%s' is too long\n", line);
            return 1;
        }

        line[strlen (line)-1] = '\0';

        // Scan the individual fields.

        if (scanf("%d %s %s %f %f %s %s %d %d", &lineNum, satNum, intDesig, 
                &epoch, &firstTimeDeriv, secondTimeDeriv, drag, &zero, &set) 
                != 9) {
            printf ("Line '%s' didn't scan properly\n", line);
            return 1;
        }

        node = malloc(sizeof(Data));
        if (node == NULL) {
            printf ("Ran out of memory\n");
            return 1;
        }

        node->lineNum = lineNum;
        node->satNum = strdup(satNum);
        node->intDesig = strdup (intDesig);
        node->epoch = epoch;
        node->firstTimeDeriv = firstTimeDeriv;
        node->secondTimeDeriv = strdup(secondTimeDeriv);
        node->drag = strdup(drag);
        node->zero = zero;
        node->set = set;
        node->next = NULL;

        if (first != NULL) {
            last->next = node;
            last = node;
        }
        else {
            first = node;
            last = node;
        }
    }
    fclose (fIn);
    node = first;
    while (node != NULL) {
        printf("%d %s %s %f %f %s %s %d %d", node->lineNum, node->satNum, 
            node->intDesig, node->epoch, node->firstTimeDeriv, 
            node->secondTimeDeriv, node->drag, node->zero, node->set);
        node = node->next;
    }
    return 0;
}

【问题讨论】:

  • 我猜你想要sscanf(line, "%d %s %s %f %f %s %s %d %d", &amp;lineNum, satNum, intDesig, &amp;epoch, &amp;firstTimeDeriv, secondTimeDeriv, //&amp;power1, drag, &amp;zero, &amp;set) 而不是scanf("%d %s %s %f %f %s %s %d %d", &amp;lineNum, satNum, intDesig, &amp;epoch, &amp;firstTimeDeriv, secondTimeDeriv, //&amp;power1, drag, &amp;zero, &amp;set)
  • 嘿,感谢您的帮助。当我尝试将其更改为“sscanf”时出现此错误:tester.c:87:15: 警告:从不兼容的指针类型传递 'sscanf' 的参数 2 [默认启用] &set) != 9){ ^ 在文件中包含自 /usr/include/features.h:374:0,来自 /usr/include/stdio.h:27,来自 tester.c:1:/usr/include/stdio.h:448:12:注意:预期'const char * restrict' 但参数类型为 'int *' extern int __REDIRECT_NTH (sscanf, (const char *__restrict __s, ^ 有什么建议吗?非常感谢!
  • 奇数。你确定你用了sscanf(line, "%d %s %s %f %f %s %s %d %d", &amp;lineNum, satNum, intDesig, &amp;epoch, &amp;firstTimeDeriv, secondTimeDeriv, drag, &amp;zero, &amp;set)(你忘了第一个参数line)吗?
  • 现在你不知道这在哪里失败了。逐步工作。 sscanf(line, "%d", &lineNum),如果可行,请添加另一个项目。您可以将其提取到一个扫描硬编码字符串的小程序中。作为一种通用方法,我总是以非常小的测试增量工作。
  • @CoolGuy:成功了。忘记了“线”的说法。我将 if 语句更改为: if(sscanf(line, "%d %s %s %f %f %s %s %d %d", &lineNum, satNum, intDesig, &epoch, &firstTimeDeriv, secondTimeDeriv, drag, &zero, &set) == 0){ printf ("行 '%s' 没有正确扫描\n", line);返回 1;现在它返回: 1 20959U 90103A 14091.587891 -0.000000 00000-0 00000+0 0 31971 20959U 90103A 14091.587891 -0.000000 00000-0 7 00000+0 0 0 39你!

标签: c list text input struct


【解决方案1】:

首先将字符数组 satnum 和 intdDesig 的大小更改为 7 即 satnum[7] 和 intDesig[7]。您想在这些保留最后一个索引中存储 6 个字符以获取空值。

if (line[strlen (line)-1] != '\n') {
        printf ("Line starting with '%s' is too long\n", line);
        return 1;
    }

这个 if 语句而不是 line[strlen(line)-1]!='\n' put this-

line[strlen(line)-1]=='\n'

语句是这样的

    if (line[strlen (line)-1]=='\n') {
        printf ("Line starting with '%s' is too long\n", line);
        return 1;
    }

并删除此行

line[strlen (line)-1] = '\0';

那么 line 不会被返回两次。

【讨论】:

    猜你喜欢
    • 2017-11-18
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多