【问题标题】:C, Code:Block, yet another sigsegv, listsC,代码:块,又一个 sigsegv,列表
【发布时间】:2014-08-28 14:36:21
【问题描述】:

大家好, 从我的教授网站空间得到这个练习。我有这种文本文件:

Simon Phillips 30
Neil Peart 45
Vinnie Colaiuta 50

我想将它存储到一个列表中,所以这是我的代码:

struct listplot {
  char name[25];
  char sur[25];
  int age;
  struct listplot *next;
};

typedef struct listplot EL;

EL *list;

int filescan(EL *current)
{
    FILE *in;
    int count=0;
    in=fopen("persone.txt", "r");
    if (ferror(in))
    {
        printf("File Error\n");
        return count;
    }
    do
    {
        current=malloc(sizeof(EL));
        fscanf(in,"%s%s%d", current->name, current->sur, &current->age);
        current->next=NULL;
        if (!feof(in)) count=count+filescan(current->next);
    }
    while (!feof(in));
    return count;
}

main 我有:

int count=filescan(list);

此代码不起作用。 在调试中,“do”循环似乎无限,但最终程序因分段错误而崩溃。 有人可以帮我吗? 非常感谢。

【问题讨论】:

  • 在没有给出最大长度的情况下不要读取字符串。并且不要假设读取​​成功。
  • 不要递归你的文件扫描函数!
  • 我为什么不能递归?为什么它不应该成功?
  • 你用你的递归无限次打开文件,总是读取第一行,还有其他错误......
  • 你递归打开文件,你的调用堆栈在不必要的时候会增加。

标签: c linked-list segmentation-fault codeblocks


【解决方案1】:

许多改进使其更加健壮:

正确初始化这个元素:

EL* list_header = NULL; /* Points to first element */

在此处增加间接级别:

int filescan(EL** current)
{

在主函数中你必须传递list_header的地址:

count = filescan(&list_header)

将此部分移动到一个函数中,该函数只关心打开文件。

FILE *in;
int count=0;
in=fopen("persone.txt", "r");
if (ferror(in))
{
    printf("File Error\n");
    return count;
}

如果 in 为 NULL 或错误则返回 0。

do
{

首先进行扫描并检查它是否填充了3个参数

    EL els = {0}; /* element for scanning */

    if (fscanf(in,"%s%s%d", els.name, els.sur, &els.age) == 3)
    {

将此移入为成功填充的 els 创建/填充/复制新 EL 的函数中

current->next = create_duplicate_EL_for(els);

/* the duplicator should malloc and fill, and set next to NULL */
    current=malloc(sizeof(EL));
    // some strcpys //
    current->next=NULL;

显然你想要计数,所以增加它。

对于循环,设置

current = current->next;

如果我们找不到正好 3 个元素,请使用 else 完成您的 scanf 分支:

    else
    {
        /* debug/error log code here */
    }
}
while (!feof(in));
return count;

【讨论】:

  • 如果我将 filescan(EL *current 更改为 filescan(EL** current 我会收到此错误 error: request for member 'name' in something not a structure or union,sur 和 age 也是如此
  • 然后你需要使用 current->name 或 (*current).name 来取消引用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多