一次C语言编程遇到的问题总结
今天用C语言做了一个简单的用户登录注册存取款等功能的系统,发现有很多功能并不会实现,大概是使用Java太多了导致许多C的知识都忘记了,现在把碰到的问题总结如下:
1、字符串复制问题
java等一些编程语言使用习惯了我们经常会用
String s1 = "abc";String s2 = s1
这种方式来给字符串赋值,但C语言一般使用的是char[]数组来存储字符串,所以在赋值的时候不可以使用单纯的赋值符"=",使用的是string.h头文件中包含的strcpy函数。如:
char a[];
char b[];
strcpy(a,b);
这样可以实现将b的值赋值给a。
2、字符串分隔问题
Java分隔字符串有专门的split函数来实现,C语言也有专门的函数实现,下面是一个实例:
char *p;
char StrLine[] = “a;b;c”;
p = strtok(StrLine,";");
while(p != NULL){
printf("%s\n",p);
p = strtok(NULL,";");
}
strtok函数:
原型:char *strtok(char s[], const char *delim);
介绍:分解字符串为一组字符串。s为要分解的字符,delim为分隔符字符(如果传入字符串,则传入的字符串中每个字符均为分割符)。首次调用时,s指向要分解的字符串,之后再次调用要把s设成NULL。
3、字符串转数字问题
例如现在有int a[3]={'1','2','3'}一个一维数组,如果要将其转换为123这个数字,我们可以这样:
1)计算a的长度,假设为n
2)分别将a[0]~a[n-1]转换为数字
3)这个数字就等于a[0]*10n-1+a[1]*10n-2+...+a[n-1]*100
这种方法确实可以实现,但是这种方法一是费时间二是费内存。
所以C语言有一个函数可以实现这种功能:atoi(a):
int atoi(const char *nptr) 函数会扫描参数 nptr字符串,会跳过前面的空白字符(例如空格,tab缩进)等。如果 nptr不能转换成 int 或者 nptr为空字符串,那么将返回 0 。特别注意,该函数要求被转换的字符串是按十进制数理解的。
附上简单实现用户登录注册存款取款修改密码的C语言代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h> //定义结构体User代表每一个用户
struct User{
char username[];//用户名
char password[];//密码
int deps;//存款数
}; struct User users[];//用户数组
struct User loginUser;//记录当前登录用户
int usersCount = ;//用户数量,默认为0 //读取文件信息
/*
由于读取文件过程中会自动读取所有数据下面的一个空行,
所以导致读取的userCount即用户数出现错误,比实际大一,
所以在执行完读取文件后,userCount需要减一
*/
void GetFileInfo(){
char *p;
char datas[][];
int i = ;
char fileName[] = "users.txt";
FILE *fp;
char StrLine[];
if((fp = fopen(fileName,"r")) == NULL)
{
printf("读取用户信息失败!");
return;
}
while(!feof(fp))
{
i = ;
fgets(StrLine,,fp);
p = strtok(StrLine," ");
while(p != NULL){
strcpy(datas[i++],p);
//printf("%s\n",p);
p = strtok(NULL," ");
}
strcpy(users[usersCount].username,datas[]);
strcpy(users[usersCount].password,datas[]);
users[usersCount].deps = atoi(datas[]);
usersCount ++;
}
usersCount -= ;
fclose(fp);
printf("读取用户信息成功~\n");
} //写入文件
void Update(){
int i = ;
FILE *fp;
fp = fopen("users.txt","w");
fclose(fp);
fp = fopen("users.txt","w");
for(i = ; i < usersCount; i++){
fprintf(fp,"%s %s %d\n",users[i].username,users[i].password,users[i].deps);
}
fclose(fp);
} //注册功能
struct User regist(){
char regist_username[];
char regist_password[];
struct User newUser;
printf("请输入用户名:");
scanf("%s",®ist_username);
printf("请输入六位密码:");
scanf("%s",®ist_password);
while(regist_password[]==NULL||regist_password[]!=NULL){
printf("密码必须是6位数,请重新输入密码:");
scanf("%s",®ist_password);
}
strcpy(newUser.username,regist_username);
strcpy(newUser.password,regist_password);
newUser.deps = ;//新注册用户余额为0
printf("注册成功!用户:%s\n",regist_username);
return newUser;
} //执行完操作后更新数组
void update(struct User user){
int i;
for(i = ; i < usersCount; i++){
if(strcmp(users[i].username,user.username) == ){
users[i] = user;
break;
}
}
} //登录后菜单选择
void menu(){
void Welcome();
int oper;
int deposit;
int withdraw;
char oldPass[];
char newPass[];
printf("***********\n");
printf("请选择:\n");
printf("1、存款\n");
printf("2、取款\n");
printf("3、查看余额\n");
printf("4、修改密码\n");
printf("5、返回\n");
printf("***********\n");
scanf("%d",&oper);
switch(oper){
case :
printf("请输入要存款的数额:");
scanf("%d",&deposit);
loginUser.deps += deposit;
printf("存款成功!余额为:%d\n",loginUser.deps);
update(loginUser);
Update();
menu();
break;
case :
printf("请输入要取款的数额:");
scanf("%d",&withdraw);
if(loginUser.deps >= withdraw){
loginUser.deps -= withdraw;
printf("取款成功!余额为:%d\n",loginUser.deps);
}else{
printf("余额不足!\n");
}
update(loginUser);
Update();
menu();
break;
case :
printf("用户:%s,您的余额为:%d\n",loginUser.username,loginUser.deps);
menu();
break;
case :
printf("请输入原密码:");
scanf("%s",&oldPass);
if(strcmp(oldPass,loginUser.password) == ){
printf("请输入新密码:");
scanf("%s",&newPass);
while(newPass[]==NULL||newPass[]!=NULL){
printf("密码必须是6位数,请重新输入密码:");
scanf("%s",&newPass);
}
strcpy(loginUser.password,newPass);
printf("更改密码成功!\n");
}else{
printf("原密码输入错误!\n");
}
update(loginUser);
Update();
menu();
break;
case :
Welcome();
}
} //登录功能
void login(){
void Welcome();
char login_username[];
char login_password[];
struct User checkUser;
int i;
printf("请输入用户名:");
scanf("%s",&login_username);
printf("请输入密码:");
scanf("%s",&login_password);
for(i = ; i < usersCount; i++){
if(strcmp(login_username,users[i].username) == ){
if(strcmp(login_password,users[i].password) == ){
loginUser = users[i];
printf("用户 %s欢迎登录!\n",login_username);
menu();
}else{
printf("密码输入错误!\n");
Welcome();
}
}
}
printf("没有这个用户!将返回\n");
Welcome();
} //欢迎界面
void Welcome(){
int select = ;
struct User user;
printf("*********************\n");
printf("欢迎来到ATM自助系统\n");
printf("*********************\n");
printf("请选择操作:\n1、用户登录\n2、用户注册\n3、退出系统\n");
scanf("%d",&select);
if(select == ){
login();
menu();
}else if (select == ){
user = regist();
users[usersCount] = user;
usersCount += ;
Update();
Welcome();
}else if (select == ){
printf("退出成功!");
exit();
}else{
printf("输入错误!将退出系统");
exit();
}
} //主函数
int main()
{
GetFileInfo();
Welcome();
return ;
}
一次C语言编程遇到的问题总结的更多相关文章
- C语言编程实现Linux命令——who
C语言编程实现Linux命令--who 实践分析过程 who命令是查询当前登录的每个用户,它的输出包括用户名.终端类型.登录日期及远程主机,在Linux系统中输入who命令输出如下: 我们先man一下 ...
- 个人c语言编程风格总结
总结一下我个人的编程风格及这样做的原因吧,其实是为了给实验室写一个统一的C语言编程规范才写的.首先声明,我下面提到的编程规范,是自己给自己定的,不是c语言里面规定的. 一件事情,做成和做好中间可能隔了 ...
- Linux下C语言编程实现spwd函数
Linux下C语言编程实现spwd函数 介绍 spwd函数 功能:显示当前目录路径 实现:通过编译执行该代码,可在终端中输出当前路径 代码实现 代码链接 代码托管链接:spwd.c 所需结构体.函数. ...
- 混合语言编程:启用CLR(公共语言运行时编译)让C#调用C++
前言 关于混合C#和C++的编程方式,本人之前写过一篇博客(参见混合语言编程:C#使用原生的Directx和OpenGL),在之前的博客中,介绍了在C#的Winform和WPF下使用原生的Direct ...
- Linux基础与Linux下C语言编程基础
Linux基础 1 Linux命令 如果使用GUI,Linux和Windows没有什么区别.Linux学习应用的一个特点是通过命令行进行使用. 登录Linux后,我们就可以在#或$符后面去输入命令,有 ...
- LINUX下C语言编程基础
实验二 Linux下C语言编程基础 一.实验目的 1. 熟悉Linux系统下的开发环境 2. 熟悉vi的基本操作 3. 熟悉gcc编译器的基本原理 4. 熟练使用gcc编译器的常用选项 5 .熟练使用 ...
- 第二章 C语言编程实践
上章回顾 宏定义特点和注意细节 条件编译特点和主要用处 文件包含的路径查询规则 C语言扩展宏定义的用法 第二章 第二章 C语言编程实践 C语言编程实践 预习检查 异或的运算符是什么 宏定义最主要的特点 ...
- 华为C语言编程规范
DKBA华为技术有限公司内部技术规范DKBA 2826-2011.5C语言编程规范2011年5月9日发布 2011年5月9日实施华为技术有限公司Huawei Technologies Co., Ltd ...
- 9 本免费的 Python 语言编程书籍(转载)
9 本免费的 Python 语言编程书籍 原文地址:http://linuxtoy.org/archives/9-free-python-books.html 2010-03-03 Toy Poste ...
- linux 操作系统下c语言编程入门
2)Linux程序设计入门--进程介绍 3)Linux程序设计入门--文件操作 4)Linux程序设计入门--时间概念 5)Linux程序设计入门--信号处理 6)Linux程序设计入门--消息管理 ...
随机推荐
- 如何用AU3调用自己用VC++写的dll函数
这问题困扰我一个上午了,终于找到原因了,不敢藏私,和大家分享一下. 大家都知道,AU3下调用dll文件里的函数是很方便的,只要一个dllcall语句就可以了. 比如下面这个: $result = Dl ...
- java编程,通过代理服务器访问外网的FTP
有些时候我们的网络不能直接连接到外网, 需要使用http或是https或是socket代理来连接到外网, 这里是java使用代理连接到外网的一些方法, 希望对你的程序有用.方法一:使用系统属性来完成代 ...
- vue 输入框数字、中文验证
vue项目是基于element框架做的,在做form表单时,要做些验证,element框架也提供了自定义验证 下面是一些常见的验证 只允许输入数字: 可以直接用框架的rule去验证,但必须在model ...
- 新闻网大数据实时分析可视化系统项目——4、Zookeeper分布式集群部署
ZooKeeper 是一个针对大型分布式系统的可靠协调系统:它提供的功能包括:配置维护.名字服务.分布式同步.组服务等: 它的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效.功能稳定的 ...
- day14-Python运维开发基础(内置函数、pickle序列化模块、math数学模块)
1. 内置函数 # ### 内置函数 # abs 绝对值函数 res = abs(-10) print(res) # round 四舍五入 (n.5 n为偶数则舍去 n.5 n为奇数,则进一!) 奇进 ...
- Android之Context和Activity互相转换
1.context转换为activity Activity activity = (Activity) context; 2.从activity得到context 在activity的方法中用cont ...
- tensorflow之逻辑回归模型实现
前面一篇介绍了用tensorflow实现线性回归模型预测sklearn内置的波士顿房价,现在这一篇就记一下用逻辑回归分类sklearn提供的乳腺癌数据集,该数据集有569个样本,每个样本有30维,为二 ...
- Day9 - G - Doing Homework HDU - 1074
有n个任务,每个任务有一个截止时间,超过截止时间一天,要扣一个分.求如何安排任务,使得扣的分数最少.Input有多组测试数据.第一行一个整数表示测试数据的组数第一行一个整数n(1<=n<= ...
- 「CF600E」Lomsat gelral
传送门 Luogu 解题思路 线段树合并板子题(也可以 dsu on the tree) 好像没什么好讲的,就是要注意开 long long . 细节注意事项 咕咕咕 参考代码 #include &l ...
- pytho 基本数据类型
1.字符串(引号) name = "........." 双引号引出来的都是字符串 name = """.........""& ...