【问题标题】:read a csv file and calculate the balance for a simple banking system in C读取 csv 文件并计算 C 中简单银行系统的余额
【发布时间】:2020-03-29 17:04:11
【问题描述】:

我刚开始学习 C 语言,但我已经卡在这里一段时间了。我知道有很多类似的问题发布了,但我找不到我的解决方案:(

所以基本上有一个名为“bankdata.csv”的文件,例如:

AC,2023,Jane Smith
TX,2023,2020-02-10,1023.34
AC,5023,Sally Long
TX,2023,2020-02,-103.34
TX,5023,2020-01-15,78.00
TX,5023,2020-03-29,22.00

您只需要查看以“TX”开头的行。数据分别代表类型、账号、日期、金额(存款为正,取款为负)。

我想做的是编写一个函数 balance() ,它将 account num 和 file 作为输入,计算特定帐户的余额并将其输出为浮点数。

这是我尝试过的:

float balance(char* num, FILE* file) {
    char line[1000];
    file = fopen ("bankdata.csv", "r");
    fgets (line, 1000, file);
    char *token = strtok (line, ","); // Extract the first token
    float bal = 0.00;

    while (token != NULL) {
        token = strtok (NULL, ","); //next token
        //printf (" %s\n", token);  
        if (strcmp (token, "TX") == 0) {
            char *acctnum = strtok (NULL, ",");
            if (strcmp (acctnum, num) == 0) {
                char *date = strtok (NULL, ",");
                char *amount = strtok (NULL, ",");
                float am = atof (amount);
                bal += am;
            }
        }

    }
    return bal;
}

在这里,我使用 while 循环来检查文件中的每一行,并为我想要的行提取“数量”,然后将它们相加。我意识到我没有处理换行符。而且我还遇到了分段错误(核心转储)。谁能帮我解决这个问题?还是有更好的方法?

到目前为止,我并不需要它高效,只希望它尽可能简单!提前谢谢你!

【问题讨论】:

  • 您需要围绕fgets() 调用——while (fgets(line, sizeof(line), file) != NULL) { … } 进行循环。在进入已有的循环之前提取第一个令牌;然后你提取第二个标记并检查它是否是TX - 它不是。也可能(可能)存在其他问题。
  • 请不要使用浮点数来赚钱。浮点数不准确。那里的人很有趣的钱。以整数衡量货币并使用便士或货币等值物
  • @JonathanLeffler 是的,谢谢!
  • 如果你在处理真实的银行账户,要么使用decimal 类型(在 C 中尚未标准化,但它们是当前 IEEE 754 标准的一部分,并且一些 FPU 芯片实现了它们 -例如 PowerPC)或使用整数类型并将“美元”(主要货币单位)乘以 100 并将分数加到其中(因此给定“3141.59”,计算3141 × 100 + 59,注意给定“2718.3” ,你需要计算2718 × 100 + 30(不仅仅是3)。小心;如果银行赔钱,人们会感到不安。
  • 最好的办法是使用long long 并计算便士。见youtube.com/watch?v=PZRI1IfStY0&t=7s

标签: c csv


【解决方案1】:

这是关于课堂练习可能接受的最小更改集 - 仍然完全忽略错误检查。

double balance(char* num, FILE* file)
{
    char line[1000];
    file = fopen("bankdata.csv", "r");             // Error checking!!!
    double bal = 0.00;

    while (fgets(line, 1000, file))
    {
        char *token = strtok(line, ",");           // Check not null
        if (strcmp(token, "TX") == 0)
        {
            char *acctnum = strtok(NULL, ",");     // Check not null
            if (strcmp(acctnum, num) == 0)
            {
                char *date = strtok(NULL, ",");    // Check not null
                char *amount = strtok(NULL, ",");  // Check not null
                double am = atof(amount);          // Check plausibility?
                bal += am;
                //printf("%s: %s: %9.2f %9.2f\n", acctnum, date, am, bal); 
            }
        }   
    }
    fclose(file);
    return bal;
}

如果这不是课堂练习,甚至使用double(而不是问题中使用的float)是非常可疑的。金钱需要小心处理。出于许多目的,最好将值存储为整数。对于大多数货币,有一些基本单位(美元、卢比、英镑、欧元),然后是一些较小单位的小数点后两位(通常是美分)。对于诸如3141.59 之类的值,您评估3141 × 100 + 59(请注意,如果给您2178.3,您需要评估2718 × 100 + 30(不仅仅是3)。有些货币对于较小的单位有三位小数(科威特第纳尔有 1000 第纳尔)。有些货币没有更小的单位;在被欧元取代之前,意大利里拉就是这样一种货币。如果可用,那么现代 IEEE 754:2019 标准定义了十进制浮点类型(@ 987654333@、decimal64decimal128);一些硬件(尤其是 IBM Power PC)对此提供支持。不过,这些十进制类型还没有标准的 C 类型。

【讨论】:

猜你喜欢
  • 2011-09-04
  • 2021-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-31
  • 1970-01-01
  • 1970-01-01
  • 2017-04-01
相关资源
最近更新 更多