C語言 項目練習-家庭收支軟件

目標

在這里插入圖片描述

需求說明

在這里插入圖片描述
在這里插入圖片描述

界面說明

登記收入界面:
在這里插入圖片描述
登記支出界面
在這里插入圖片描述
收支明細界面
在這里插入圖片描述
退出界面
在這里插入圖片描述

項目代碼改進要求

在這里插入圖片描述

自己完成的代碼

版本1

#include<stdio.h>
#include<string.h>
void choose(int button,int i);
//項目--家庭收支軟件
static double total=10000;//總金額
#define SIZE 100
//用來接收收支信息
struct Count{char *name;double money;char info[100];
}count[100];
int main()
{int d=0;char c='0';int i=0;//統計記錄個數printf("---------家庭收支軟件--------\n");printf("         1.收支明細\n         2.登記收入\n         3.登記支出\n         4.退出\n");while(1){printf("請選擇(1-4):");scanf("%d",&d);getchar();//接收回車enterif(d==4){printf("是否確認退出(y/n):");//輸入的是字符串scanf("%c",&c);getchar();//接收回車enter,一定要記得接收回車符if(c=='y'){break;//退出while循環}}else{choose(d,i);if(d==2||d==3){i++;}}}fflush(stdin);//刷新getchar();return 0;
}
void choose(int button,int i)
{int k;if(button==1)//收支明細{printf("---------當前收支明細記錄--------\n");printf("收支\t\t收支金額\t\t總金額\t\t說明\n");if(i==0){printf("無\t\t0.00\t\t\t%.2f\t無\n",total);}else{for(k=0;k<i;k++){printf("%s\t\t%.2f\t\t\t%.2f\t%s\n",count[k].name,count[k].money,total,count[k].info);}}printf("\n---------------------------------\n");}else if(button==2)//登記收入{count[i].name="收入";printf("本次收入金額:");scanf("%lf",&count[i].money);printf("本次收入說明:");scanf("%s",count[i].info);total+=count[i].money;}else if(button==3)//登記支出{count[i].name="支出";printf("本次支出金額:");scanf("%lf",&count[i].money);printf("本次支出說明:");scanf("%s",count[i].info);total-=count[i].money;}}

版本2

#include<stdio.h>
#include<string.h>
void choose(int button,int i);
//項目--家庭收支軟件
static double total=10000;//總金額
//用來接收收支信息
struct Count{char *name;//每一次收支的名稱:收入or支出double money;//每一次收支的金額char info[100];//每一次收支的信息double all;//每一次收支后的總金額
}count[100];
int main()
{int d=0;char c='0';int i=0;//統計記錄個數printf("---------家庭收支軟件--------\n");printf("         1.收支明細\n         2.登記收入\n         3.登記支出\n         4.退出\n");while(1){printf("請選擇(1-4):");scanf("%d",&d);getchar();//接收回車enterif(d==4){printf("是否確認退出(y/n):");//輸入的是字符串scanf("%c",&c);getchar();//接收回車enter,一定要記得接收回車符if(c=='y'){break;//退出while循環}else if(c=='n'){continue;}else{printf("輸入錯誤\n");}		}else{choose(d,i);if(d==2||d==3){i++;}}}fflush(stdin);//刷新getchar();return 0;
}
void choose(int button,int i)
{int k;if(button==1)//收支明細{printf("---------當前收支明細記錄--------\n");printf("收支\t\t收支金額\t\t總金額\t\t說明\n");if(i==0){printf("無\t\t0.00\t\t\t%.2f\t無\n",total);printf("當前沒有收支明細...來一筆吧!\n");}else{for(k=0;k<i;k++){printf("%s\t\t%.2f\t\t\t%.2f\t%s\n",count[k].name,count[k].money,count[k].all,count[k].info);}}printf("\n---------------------------------\n");}else if(button==2)//登記收入{count[i].name="收入";printf("本次收入金額:");scanf("%lf",&count[i].money);printf("本次收入說明:");scanf("%s",count[i].info);total+=count[i].money;count[i].all=total;}else if(button==3)//登記支出{count[i].name="支出";printf("本次支出金額:");double temp=0;//臨時存儲支出金額scanf("%lf",&temp);getchar();//過濾enterif(temp>total){printf("當前余額不足,不能支出\n");}else{count[i].money=temp;printf("本次支出說明:");scanf("%s",count[i].info);total-=count[i].money;count[i].all=total;}		}}

案例代碼

案例代碼版本1

#include<stdio.h>
#include<string.h>
//項目--家庭收支軟件(teacher)--代碼版本1
int main()
{//所有的局部變量在使用前要初始化int loop=1;//控制最外層do--while循環int num=0;//用戶選擇的數字char quit='0';//用戶選擇是否退出的操作:y/ndouble total=1000;//總金額double money=0;//每次收支金額char detail[100];//每次收支說明char info[3000]="";//要顯示的所有明細char s[1000]="";//每次收支明細的臨時數組int n=0;//統計是否有至少一筆收支明細記錄,1為有,0為無//初始化detail數組memset(detail,0,sizeof(detail));do{printf("------家庭收支軟件--------\n");printf("--------1.收支明細--------\n--------2.登記收入--------\n--------3.登記支出--------\n--------4.退出-----------\n");printf("請選擇(1-4):");scanf("%d",&num);getchar();//過濾enterswitch(num){//使用switch對每種選擇結果做出反應case 1://收支明細printf("收支\t\t收支金額\t總金額\t說明\n");printf("%s",info);if(!n){printf("當前沒有收支明細..來一筆吧!\n");}break;case 2://登記收入printf("本次收入金額:");scanf("%lf",&money);getchar();//enterprintf("本次收入說明:");scanf("%s",detail);getchar();//entertotal+=money;sprintf(s,"收支\t\t%.2f\t\t%.2f\t%s\n",money,total,detail);strcat(info,s);n=1;//有一筆明細記錄break;case 3://登記支出printf("本次支出金額:");scanf("%lf",&money);getchar();//enterif(money>total){printf("能夠支出的金額不夠\n");}else{printf("本次支出說明:");scanf("%s",detail);getchar();//entertotal-=money;sprintf(s,"收支\t\t%.2f\t\t%.2f\t%s\n",money,total,detail);strcat(info,s);n=1;//有一筆明細記錄}break;case 4://退出do{printf("確認是否退出(y/n):");scanf("%c",&quit);getchar();//enterif(quit=='y'||quit=='n'){break;//跳出此do-while循環}else{printf("輸入錯誤!\n");}}while(1);//循環執行退出詢問if(quit=='y'){loop=0;//結束最外層do-while循環}break;}}while(loop);//循環輸出getchar();return 0;
}

案例代碼版本2

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//項目--家庭收支軟件(teacher)--代碼版本2--結構體+函數
//所有的局部變量在使用前要初始化
int loop=1;//控制最外層do--while循環
char info[3000]="";//要顯示的所有明細
char s[1000]="";//每次收支明細的臨時數組
int num=0;//用戶選擇的數字
char quit='c';//用戶選擇是否退出的操作:y/n//家庭賬戶結構體
struct Account{double total;//總金額double money;//每次收支金額char detail[100];//每次收支說明int n;//統計是否有至少一筆收支明細記錄,1為有,0為無};//支出
void pay(struct Account*count)
{printf("本次支出金額:");scanf("%lf",&(*count).money);getchar();//enterif((*count).money>(*count).total){printf("能夠支出的金額不夠\n");}else{printf("本次支出說明:");scanf("%s",(*count).detail);getchar();//enter(*count).total-=(*count).money;sprintf(s,"收支\t\t%.2f\t\t%.2f\t%s\n",(*count).money,(*count).total,(*count).detail);strcat(info,s);(*count).n=1;//有一筆明細記錄}
}
//收入
void income(struct Account*count)
{printf("本次收入金額:");scanf("%lf",&(*count).money);getchar();//enterprintf("本次收入說明:");scanf("%s",(*count).detail);getchar();//enter(*count).total+=(*count).money;sprintf(s,"收支\t\t%.2f\t\t%.2f\t%s\n",(*count).money,(*count).total,(*count).detail);strcat(info,s);(*count).n=1;//有一筆明細記錄}
//所有明細
void show(struct Account*count)
{printf("收支\t\t收支金額\t總金額\t說明\n");printf("%s",info);if(!(*count).n){printf("當前沒有收支明細..來一筆吧!\n");}}
//退出
void esc()
{do{printf("確認是否退出(y/n):");scanf("%c",&quit);getchar();//enterif(quit=='y'||quit=='n'){break;//跳出此do-while循環}else{printf("輸入錯誤!\n");}}while(1);//循環執行退出詢問if(quit=='y'){loop=0;//結束最外層do-while循環}
}
//顯示菜單
void menu(struct Account*count)
{do{printf("------家庭收支軟件--------\n");printf("--------1.收支明細--------\n--------2.登記收入--------\n--------3.登記支出--------\n--------4.退出-----------\n");printf("請選擇(1-4):");scanf("%d",&num);getchar();//過濾enterswitch(num){//使用switch對每種選擇結果做出反應case 1://收支明細show(count);break;case 2://登記收入income(count);break;case 3://登記支出pay(count);break;case 4://退出esc();break;}}while(loop);//循環輸出
}
int main()
{struct Account*count;//在使用指針時要為指針分配內存空間 struct Account*count=(struct Account*)malloc(20*sizeof(struct Account*));//初始化結構體成員(*count).n=0;//初始化detail數組memset((*count).detail,0,sizeof((*count).detail));(*count).money=0;(*count).total=1000;	menu(count);getchar();return 0;
}

寫代碼時遇到的知識點

1.使用memset()去初始化局部變量
C語言中系統只會自動初始化全局變量

定義變量時一定要進行初始化,尤其是數組和結構體這種占用內存大的數據結構。在使用數組的時候經常因為沒有初始化而產生“燙燙燙燙燙燙”這樣的野值,俗稱“亂碼”

memset() 函數可以說是初始化內存的“萬能函數”,通常為新申請的內存進行初始化工作。它是直接操作內存空間

使用# include <string.h>
void *memset(void *s, int c, unsigned long n);
memset(s,0,3000);

函數的功能是:將指針變量 s 所指向的前 n 字節的內存單元用一個“整數” c 替換,注意 c 是 int 型。s 是 void* 型的指針變量,所以它可以為任何類型的數據進行初始化。

memset(s,0,3000);
將數組s的前3000個字節的內存單元全部初始化為0,即對數組進行清0

記憶: memset(s,0,sizeof(s));

結構體中的字符數組和字符指針
1)
C語言只有在定義字符數組的時候才能用“=”來初始化變量,其它情況下是不能直接用“=”來為字符數組賦值的,要為字符數組賦值可以用string.h頭文件中的strcpy函數來完成。
例如:
char a[10] = “123”; /正確,在定義的時候初始化/

char a[10];
a = “123”; /錯誤,不能用“=”直接為字符數組賦值/
strcpy(a, “123”); /正確,使用strcpy函數復制字符串/

所以這里不能使用myFamilyAccout.details=”xx”;

補充:
用char c[20]定義的,用strcpy拷貝來賦值, strcpy(c, “123”);
用char *p定義的,用=來賦值,p=”iio”;(記得分配地址給指針)

struct mem
{
char name[20];
char name;
};
結構體中使用char
name出現問題的解決方案:
char name[20];是有著自己連續的一塊內存空間的
char *name;僅僅是個指針,是一個標記,沒有分配用來保存字符串的空間
要使用指針,記得分配空間,不然肯定各種錯誤
有2種解決方案:
1、
char *name;
char n[20];
name=n;

2、
char *name;
name=(char *)malloc(sizeof(char)*20);

由于大小為20個字節,所以除了最后一位字符串結束標記外還可以存放19個字節。
前者效率高些,后者用完后可以用free()釋放空間

案例

#include<stdio.h>
#include<stdlib.h>
#define NUM 2
struct mem
{char *name;char phone[10];
};
void main()
{struct mem man[NUM];char c[20];int i;for(i=0;i<NUM;i++){man[i].name=(char*)malloc(20*sizeof(char));//為結構體指針動態分配地址//方式2:新建立一個數組,讓指針指向數組地址//man[i].name=c;printf("input name:\n");gets(man[i].name);printf("input phone:\n");gets(man[i].phone);}printf("name\t\t\tphone\n\n");for(i=0;i<NUM;i++){printf("%s\t\t\t%s\n",man[i].name,man[i].phone);free(man[i].name);//釋放指針內存空間}getchar();
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/446525.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446525.shtml
英文地址,請注明出處:http://en.pswp.cn/news/446525.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c++ fmt 庫安裝和使用示例、clion配置

安裝 git clone https://github.com/fmtlib/fmt.gitmake .mkae && make install CLion使用 使用和安裝存在出入下載源碼&#xff0c;可以先 clone 到你的項目中去&#xff0c;https://github.com/fmtlib/fmt &#xff0c;我放到的是項目的 dependencies 目錄然后在…

C語言 項目 CRM系統(客戶信息管理系統)

項目目標 項目需求說明 系統界面 1)添加客戶界面 通過編號來區分客戶 2)刪除客戶界面 對用戶輸入的編號進行核查,存在與否,合法與否 3)顯示客戶列表界面 4)修改客戶信息的界面 項目設計 Customer結構體的設計 CRM系統結構框架圖 案例代碼 #include <stdio.h>…

代碼重構 防火墻 相關知識

參考 依據Linux命令以及sysconf下現有的iptables命令&#xff0c;詳見hsm_sysconf_server/src/sysconf_server.cpp中的firewall規則。 接口名稱 firewall_manager 目的(現實) 根據網口直連獲取當前eth0和eth1的各種信息保證設置的正確性 以及要針對管理口和服務口設計不…

C語言 文件的基本介紹

基本介紹 輸入流與輸出流 重點在C程序(內存)的數據移動方向 對于C程序(內存) 輸入數據:輸入流 輸出數據:輸出流 輸入 和輸出 C標準庫 標準輸入輸出庫 標準文件 getchar()&putchar()函數 代碼 #include<stdio.h> #include<stdlib.h> //文件--getchar()和…

ubuntu修改字體 樣式

使用 快捷鍵 ctrlaltt 打開終端安裝gnome-tweaks桌面管理工具 sudo apt install gnome-tweaksaltf2 在運行窗口輸入 gnome-tweaks 命令&#xff0c;然后回車打開優化窗口&#xff0c;選擇第二個front字體選項ubuntu顯示中文

C語言 文件的讀寫

引入 OS操作系統 打開文件fopen()函數 讀寫模式: r:讀取已有文件 w:文件不存在,創建文件并寫入文件.文件存在,內容清零,再寫入文件 a: 文件不存在,創建文件并寫入文件.文件存在,以追加的形式寫入文件 r:讀寫已有文件 w:文件不存在,創建文件并讀寫文件.文件存在,內容清零,再…

StarWind V2V Image Converter:虛擬機鏡像轉換工具,可將 IMG 文件轉換為 VMware VMDK 文件

操作流程 選擇本地的需要轉換的文件找到源文件的路徑&#xff0c;img格式選擇轉化后的格式 第一個選擇 第二個 速度快一些選擇將轉化后的文件的存儲路徑軟件的下載鏈接 鏈接: https://pan.baidu.com/s/1Fe6yI42Zz9d_Q7aUhGe1FQ 提取碼: 5vmv

數學建模基礎知識

原型與模型 模型的分類 數學建模 數學建模的分類 成為建模大神 數學建模比賽 數學建模一般步驟 數學建模全過程 數學建模論文寫作 1&#xff09;摘要:是決定最后獲獎等級的關鍵 2&#xff09;問題重述:使用自己的語言將問題重述一次 3&#xff09;符號說明:對于常見的或…

數學建模 線性規劃模型基本原理

線性規劃問題 例1.1 可行解&可行域 matlab標準形式及軟件求解 標準形式: C稱為價值向量 如果是求max,加一個負號-c^T 如果是求Ax>b,加一個負號-Ax<b 使用matlab求線性規劃例題 求解的是最大值:加上負號 y是求解的最優解 zeros()使用: zeros(n)&#xff1a;生…

接上文 ,解決 虛擬機VM,U盤(磁盤)裝有系統,將其中系統安裝到另外一塊磁盤的具體操作

問題原因&#xff1a;接上文&#xff0c;將生成的vsdk格式的磁盤導入VM創建鏡像&#xff0c;相關于U盤裝載系統鏡像&#xff0c;將U盤其中的鏡像導入到磁盤里邊&#xff0c;U盤是引導&#xff0c;會將系統最終裝載到磁盤出錯原因是因為 沒有新建第二塊磁盤 解決 新增一塊磁盤如…

數學建模 層次分析法

簡介 針對多目標,多準則或無結構特性的復雜決策問題 步驟 解決評價類問題 評價類問題: 資料查找: 1)查找相關文獻 2)如果沒有找到相關文獻 3)搜索 通過上述步驟后得到的結果 構建層次結構模型 舉例: 成對比較矩陣 標度表: 奇數:越大越重要 偶數:上述兩相鄰判斷的中值…

ubuntu配置靜態IP地址

sysconf_client update -t network -j {"netdev":"eth0","ip":"a.b.c.d","mask":"255.255.255.0"}

接上文 VM安裝的ubuntu系統,配置雙網卡

點擊編輯 進入虛擬網絡編輯器 點擊更改設置 補充&#xff1a;如何判定橋接至哪張網卡&#xff1f;進入win&#xff0c;winr 輸入cmd&#xff1b;輸入 systeminfo選中系統&#xff0c;點擊右鍵&#xff0c;選中設置 重啟系統使用 ifconfig查看&#xff0c;發現有eth0和eth1…

數學建模 趣味數模問題(數模入門)

狼羊人菜渡河問題 解答 試探法 因為有4個變量,所以一共有222*216種狀態 找出其中不安全的狀態:無人看守的狀態下:狼羊一起,羊菜一起 人 狼 羊 菜(0是在對面,1是在這邊) 狼羊一起:(0,1,1,0) (0,1,1,1) (1,0,0,0) (1,0,0,1) 羊菜一起:(0,0,1,1) (1,1,0,0) 其余的10個都是安全狀態…

數學建模 整數規劃的基本原理和標準形式

整數規劃模型 變量限制為整數 一般解決運輸問題和整數問題 分類: 研究的是純整數規劃問題 整數規劃特點 實數的解不能直接四舍五入為整數,因為此時可能不滿足約束條件 舉例-合理下料問題 模型: 題目: 這是在使用材料 1)使用零件A1-Am毛胚,就是使用零件 2)下料方式B1-Bn就…

程序員 面試筆記 C++ 程序設計的基礎 第10章

10.1.1 程序的編譯和執行 以#開頭的代碼都屬于預處理器處理的步驟#include 將頭文件的內容包含進入當前源文件中#define 展開宏定義#ifdef 處理條件編譯指令(#ifdef、ifndef、#if、#else、#elif、#endif)#other 處理其他宏指令(#error、#warning、#line、#pragma) 預…

數學建模 分支限界算法求解整數規劃原理以及編程實現

引入 線性規劃問題(松弛問題) 圖解法: 使用圖解法求出最優解,再使用四舍五入求出的整數解不滿足條件 完全枚舉法(窮舉法):找出集合內所有滿足條件的整數點,再帶入不等式中,看是否有最優解 分支限界法 說明: 松弛問題:線性規劃問題 ILP:整數規劃,在線性規劃的基礎上對決策…

java Map統計字符串中元素的數量

public int firstUniqChar(String s) {Map<Character, Integer> map new HashMap();char[] chars s.toCharArray();//先統計每個字符的數量for (char ch : chars) {map.put(ch, map.getOrDefault(ch, 0) 1);}//然后在遍歷字符串s中的字符&#xff0c;如果出現次數是1就…

數學建模 割平面算法求解整數規劃基本原理與編程實現

基本思想 松弛問題:線性規劃 割掉一塊全部都是小數的區域(這一部分取不到整數) 案例 1)橫坐標x1,縱坐標x2 2)藍色小三角形的區域:x2:(1,7/4) x1:(0,3/4) 這塊區域,x1與x2完全取不到整數,所以直接切去 所以,此時取值范圍變化了: x2<1把此約束條件帶入,得到x11,x21,z2 3…