更新CSV文件中的特定列和行

时间:2019-01-12 14:20:35

标签: c

我和我的朋友正在研究一个简单的ATM项目(事实证明它并不像刚开始听起来那么简单),我们认为它适合像我们这样的初学者。该控制台应用程序将允许用户注册一个帐户,然后登录以进行其他提款/存款工作。我们可以成功地将客户信息写到CSV文件上,然后对其进行解析以进行ID和密码检查,并允许用户使用其他功能。

我们无法确定的是如何更新某个字符串。假设ID为64的用户登录并想取款。然后,程序必须找到以CSV格式排列的客户行,并更新相应的列(例如第5列)以减去一定金额。

我们尝试实现fseekfscanf失败。我们应该研究什么功能?

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

int loginState = 0, line=0; /*Kept the line variable as a global one so I can set the cursor to desired line if needed */

struct Customers customer;
struct Customers{
    int id;
    char fname[20];
    char lname[20];
    int password;
    int cashAmount;
};

void registerAccount(){
    srand(time(NULL));
    customer.id = rand()%99999;

    FILE *cstm = fopen("customers.csv", "a+");

    printf("An ID is set automatically for you.\n");
    printf("Please enter your first name.\n");
    scanf("%s", customer.fname);
    printf("Please enter your last name.\n");
    scanf("%s", customer.lname);
    printf("Please set a password.\n");
    scanf("%d", &customer.password);
    customer.cashAmount = 0;

    fprintf(cstm, "%d,%s,%s,%d,%d\n", customer.id, customer.fname, customer.lname, customer.password, customer.cashAmount);
    fclose(cstm);
}

int parser(int idSearch, int passwordCheck){ /*Takes input from login() function and does an ID and password check*/
    char lineBuffer[255];

    FILE *cstm = fopen("customers.csv", "r");

    while(fgets(lineBuffer,sizeof(lineBuffer),cstm))
    {
        ++line;
        char* id = strtok(lineBuffer, ",");
        if (atoi(id) == idSearch){
            customer.id = atoi(id);

            char* fname = strtok(NULL, ",");
            if (fname != NULL){
                strcpy(customer.fname, fname);
            }

            char* lname = strtok(NULL, ",");
            if (lname != NULL){
                strcpy(customer.lname, lname);
            } 

            char* password=strtok(NULL, ",");
            if (password != NULL){
                if(atoi(password) == passwordCheck){
                    customer.password = atoi(password);
                    loginState = 1;
                }
                else{
                    printf("You have entered the wrong password.\n");
                }
            }       

            char* cashAmount=strtok(NULL, "\n");
            if (cashAmount != NULL){
                customer.cashAmount = atoi(cashAmount);
            }
            fclose(cstm);
            return 1;
        }
    }
    printf("Could not find the ID.\n");
    fclose(cstm);
}

int login(){
    int passwordCheck, idSearch;

    printf("Please put your ID in.\n");
    scanf("%d", &idSearch);
    printf("Please put your password.\n");
    scanf("%d", &passwordCheck);

    if(parser(idSearch, passwordCheck) == 1){
        return 1;
    }
}

void balanceOperations(int option){
    int amount;
    FILE *cstm = fopen("customers.csv", "a+");

    if(option == 1){
        printf("\nYour current balance is: %d dollars.\n", customer.cashAmount);
        printf("How much would you like to deposit?\n");
        scanf("%d", &amount);
        customer.cashAmount = customer.cashAmount + amount;
        /* update function comes here */
        printf("Your new balance is %d dollars.\n", customer.cashAmount);
    }

    else if(option == 2){
        printf("\nYour current balance is: %d dollars.\n", customer.cashAmount);
        printf("How much would you like to withdraw?\n");
        scanf("%d", &amount);
        customer.cashAmount = customer.cashAmount - amount;
        printf("Your new balance is %d dollars.\n", customer.cashAmount);
    }

    else{
        printf("Something went wrong. Terminating in 5 seconds...\n");
        sleep(5);
        exit(0);
    }
}

void transaction(){

}

void loginChoices(){
    int answer;

    printf("Please select an operation.");

    while(1){
    printf("\n1. Deposit\n2. Withdraw\n3. Transaction\n");
    scanf("%d", &answer);
    switch(answer){
        case 1:
            balanceOperations(answer);
            break;
        case 2:
            balanceOperations(answer);
            break;
        case 3:
            transaction(answer);
            break;
        default:
            printf("\nInvalid request. Please enter a valid option.\n");
    }
}
}

int main(){

    int answer;

    printf("\nWelcome.\nPlease enter the digit of corresponding operation.\n");
    printf("1. Login.\n2. Register.\n");
    scanf("%d",&answer);

    if(answer == 1){
        if(login() == 1 && loginState == 1){
            printf("\nYou have logged in successfully.\n");
            printf("Your current balance is: %d dollars.\n\n", customer.cashAmount);
            loginChoices();
        }
    }

    else if(answer == 2){
        registerAccount();
    }

    else{
        printf("Please enter a valid number.\n");
        exit(0);
    }
}

1 个答案:

答案 0 :(得分:1)

我会说,您在维护程序中的现有客户和行内客户的全局变量方面存在全局变量,因此您在设计程序方面做得不好。


无论如何对当前代码的编辑都不多,您可以执行以下操作。

在代码注释中找到我的解释。

void balanceOperations(int option){
    int amount;
    FILE *cstm = fopen("customers.csv", "r+"); //Open file for update, not a+

    FILE *tempFile = fopen("temp.csv", "w+");

    char lineBuffer[255];
    int temp = line-1;  //Your global variable which maintains the line number


    /*Loop till you get the current customer from the file*/
    while(fgets(lineBuffer,sizeof(lineBuffer),cstm))
    {
            if(option == 1){

                if (!temp)
                {
                   printf("\nYour current balance is: %d dollars.\n", customer.cashAmount);
                   printf("How much would you like to deposit?\n");
                   scanf("%d", &amount);

                   customer.cashAmount = customer.cashAmount + amount;

                   /*Overwrite the correct amount*/
                   fprintf(tempFile, "%d,%s,%s,%d,%d\n", customer.id, customer.fname, customer.lname, customer.password, customer.cashAmount);
                   printf("Your new balance is %d dollars.\n", customer.cashAmount);


                }
                else
                {
                     fputs(lineBuffer, tempFile);
                }
            }
            else if(option == 2){
                printf("\nYour current balance is: %d dollars.\n", customer.cashAmount);
                printf("How much would you like to withdraw?\n");
                scanf("%d", &amount);
                if (!temp)
                {
                   customer.cashAmount = customer.cashAmount - amount;

                   /*Overwrite the correct amount*/
                   fprintf(tempFile, "%d,%s,%s,%d,%d\n", customer.id, customer.fname, customer.lname, customer.password, customer.cashAmount);
                   printf("Your new balance is %d dollars.\n", customer.cashAmount);
                }
                else
                {
                     fputs(lineBuffer, tempFile);
                }
            }
            else{
                printf("Invalid operation. Terminating in 5 seconds...\n");
                exit(5);
            }
            temp--;
      }
      fclose(cstm);
      fclose(tempFile);
      remove("customers.csv");
      rename ("temp.csv","customers.csv");
 }