【问题标题】:Putting values inside linked list header while using fgets()使用 fgets() 时将值放入链表标题中
【发布时间】:2019-11-23 03:11:12
【问题描述】:

我一直在处理一项任务,其中给了我们一个 .ssv 文件,其中包含第一列中的银行账户和第二列中的交易(20 是增加 20 美元,-20 是带走 20 美元),并被要求使用多个 c 文件创建帐户的链接列表。

有三个问题:main.c(打开 ssv 并逐行运行)、ssv.c(包含从 fgets() 字符串中解析出数据的函数)和 linked.c(创建链接的通过匹配帐号并添加交易来列出和更新账户余额)。它们必须保持独立,不能制成 .h 文件。

就我的代码目前而言,它不会被放入我的链表标题中,因为如果我只是让它直接写入标题,它会在 while(fgets()) 的每次迭代中被覆盖。因此,我正在寻找某种方法将第一行写入标题,然后循环像往常一样继续,添加新帐户或更新当前帐户中的交易。我还注意到它似乎没有更新交易金额,因为它只是将账户 10 列为没有钱。任何地方的任何输入都将不胜感激。

./bank 输出:

ctonne2, ~/Projects/COMP206/Assignments/ass6: ./bank
ACCOUNT ID:    0 BALANCE: $    0.00
ACCOUNT ID:   10 BALANCE: $    0.00

main.c:


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

void main() {
        FILE* ssv = fopen("students.ssv", "rt");
        if (ssv == NULL) {
                printf("\n File opening failed");
                exit(1);
        }

        int acct = 0;
        float amnt = 0;

        char line [100], bankAcc[10], balChange[10];
        while (fgets(line, sizeof(line), ssv)) {
                parse(line,&acct, &amnt);
                findUpdate(acct, amnt);
        }
        prettyPrint();
}

linked.c:

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

struct ACCOUNT {
        int accountNumber;
        float balance;
        struct ACCOUNT* next;
};

struct ACCOUNT* head = NULL;

void findUpdate(int account, float amount) {

        head = (struct ACCOUNT*)malloc(sizeof(struct ACCOUNT));

        if (head == NULL) exit (1);

        struct ACCOUNT* current = head;

        int changed = 0;

        while(current->next != NULL) {
                if (current->accountNumber == account) {
                        current->balance = current->balance + amount;
                changed++;
                }
        current = current->next;
        }

        if ((changed==0)&&(current->next==NULL)) {
        struct ACCOUNT* newAccount=(struct ACCOUNT*)malloc(sizeof(struct ACCOUNT));
                if (newAccount == NULL) exit(1);
                current->next=newAccount;
                newAccount->accountNumber = account;
                newAccount->balance = amount;
                newAccount->next = NULL;

        }
}

void prettyPrint() {
        struct ACCOUNT *current = head;
        while (current!=NULL) {
                printf("ACCOUNT ID: %4d BALANCE: $ %7.2f \n",current->accountNumber, current->balance);
                current = current->next;
        }
}

ssv.c

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

void parse(char record[], int *acct, float *amnt) {
        char *end;
        char acctarr[10], amntarr[10];
        sscanf (record, "%d %f", acct, amnt);
        return;
}

.ssv 文件示例

10 100.0 
20 -50.5 
10 -20.0

【问题讨论】:

    标签: c linked-list


    【解决方案1】:

    1) 每次尝试更新平衡时,您都在初始化列表。 只有当它指向 NULL 时才应该初始化它

    if(head == NULL){
            head = (struct ACCOUNT*)malloc(sizeof(struct ACCOUNT));
            head->accountNumber = account;
            head->balance = 0;
    }
    

    2) 您的 while 条件对于保存尾部是可以的,但对于会计来说是错误的。 当您浏览列表时,您将跳过最后一个帐户但保留尾部。 您应该更改保留 tail 的方式以处理列表中的最后一个条目。 这是一个使用迭代器保存尾部的选项:

    while(1){
        if (current->accountNumber == account) {
            current->balance = current->balance + amount;
            changed++;
        }
        if(current->next == NULL){
            break;
        }
        current = current->next;
    }
    

    当然,当您不将同一个变量用于多种用途时,代码的可读性会更高。

    struct ACCOUNT* tail = head;
    while(current){
      if (current->accountNumber == account) {
          current->balance = current->balance + amount;
          changed++;
      }
      tail = current;
      current = current->next;
    }
    
    if ((changed==0)&&(tail->next==NULL)) {
        struct ACCOUNT* newAccount=(struct ACCOUNT*)malloc(sizeof(struct ACCOUNT));
        tail->next=newAccount;
        newAccount->accountNumber = account;
        newAccount->balance = amount;
        newAccount->next = NULL;
    }
    

    【讨论】:

    • 虽然这修复了header不包含任何账户的错误,但由于某种原因,账户余额仍然拒绝更新。我想知道是不是parse()函数没有返回正确值的错误?
    • 解析没问题。很可能你没有正确应用我的一个补丁。
    • 我运行了代码,尽管逐字复制了代码,但由于某种原因,0 仍然出现在平衡区域。我怀疑这可能与 while 循环或新的中断有关。 @maxim
    猜你喜欢
    • 2014-10-07
    • 1970-01-01
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    • 2020-02-17
    • 2019-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多