【发布时间】:2019-01-12 14:20:35
【问题描述】:
我和我的朋友正在研究一个简单的(事实证明它并不像一开始听起来那么简单)ATM 项目,我们认为该项目适合像我们这样的初学者。这个控制台应用程序可以让用户注册一个帐户,然后登录做其他取款/存款的事情。我们可以成功地将客户信息写入 CSV 文件,然后对其进行解析以进行 ID 和密码检查,并让用户进入以使用其他功能。
我们不知道如何更新某个字符串。假设 ID 为 64 的用户登录并想要取款。然后程序必须找到客户在 CSV 上的行并更新相应的列(例如第 5 列)以减去一些金额。
我们尝试实现fseek 和fscanf,但没有成功。我们应该研究什么功能?
#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);
}
}
【问题讨论】:
-
如果更新改变了数据的长度,你就有问题了。如果您将固定大小的记录写入文件,这不是问题,但使用
printf()是。要使用不同大小的条目更新文件,到目前为止,最简单(通常也是最有效)的技术是制作文件副本,并在适当时编辑条目(或条目)。老式大型机批处理将这一点发挥到了极致,但即便如此,通常也使用固定大小的记录。
标签: c