今天用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",&regist_username);
printf("请输入六位密码:");
scanf("%s",&regist_password);
while(regist_password[]==NULL||regist_password[]!=NULL){
printf("密码必须是6位数,请重新输入密码:");
scanf("%s",&regist_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语言编程遇到的问题总结的更多相关文章

  1. C语言编程实现Linux命令——who

    C语言编程实现Linux命令--who 实践分析过程 who命令是查询当前登录的每个用户,它的输出包括用户名.终端类型.登录日期及远程主机,在Linux系统中输入who命令输出如下: 我们先man一下 ...

  2. 个人c语言编程风格总结

    总结一下我个人的编程风格及这样做的原因吧,其实是为了给实验室写一个统一的C语言编程规范才写的.首先声明,我下面提到的编程规范,是自己给自己定的,不是c语言里面规定的. 一件事情,做成和做好中间可能隔了 ...

  3. Linux下C语言编程实现spwd函数

    Linux下C语言编程实现spwd函数 介绍 spwd函数 功能:显示当前目录路径 实现:通过编译执行该代码,可在终端中输出当前路径 代码实现 代码链接 代码托管链接:spwd.c 所需结构体.函数. ...

  4. 混合语言编程:启用CLR(公共语言运行时编译)让C#调用C++

    前言 关于混合C#和C++的编程方式,本人之前写过一篇博客(参见混合语言编程:C#使用原生的Directx和OpenGL),在之前的博客中,介绍了在C#的Winform和WPF下使用原生的Direct ...

  5. Linux基础与Linux下C语言编程基础

    Linux基础 1 Linux命令 如果使用GUI,Linux和Windows没有什么区别.Linux学习应用的一个特点是通过命令行进行使用. 登录Linux后,我们就可以在#或$符后面去输入命令,有 ...

  6. LINUX下C语言编程基础

    实验二 Linux下C语言编程基础 一.实验目的 1. 熟悉Linux系统下的开发环境 2. 熟悉vi的基本操作 3. 熟悉gcc编译器的基本原理 4. 熟练使用gcc编译器的常用选项 5 .熟练使用 ...

  7. 第二章 C语言编程实践

    上章回顾 宏定义特点和注意细节 条件编译特点和主要用处 文件包含的路径查询规则 C语言扩展宏定义的用法 第二章 第二章 C语言编程实践 C语言编程实践 预习检查 异或的运算符是什么 宏定义最主要的特点 ...

  8. 华为C语言编程规范

    DKBA华为技术有限公司内部技术规范DKBA 2826-2011.5C语言编程规范2011年5月9日发布 2011年5月9日实施华为技术有限公司Huawei Technologies Co., Ltd ...

  9. 9 本免费的 Python 语言编程书籍(转载)

    9 本免费的 Python 语言编程书籍 原文地址:http://linuxtoy.org/archives/9-free-python-books.html 2010-03-03 Toy Poste ...

  10. linux 操作系统下c语言编程入门

    2)Linux程序设计入门--进程介绍 3)Linux程序设计入门--文件操作 4)Linux程序设计入门--时间概念 5)Linux程序设计入门--信号处理 6)Linux程序设计入门--消息管理  ...

随机推荐

  1. JSON传输图片帮助类

    JSON传输图片帮助类 2014-05-27 16:11:22|  分类: Java |  标签:解决方案  java  json  |举报|字号 订阅     原理:将图片转换为字节流,再将字节流用 ...

  2. Iterator作用

    前言 下面的内容是我从百度知道拷贝出来的,也就不在贴出链接了.我总结下就是迭代器在集合中使用,用户不需要关心具体集合实现的是如何遍历(不暴露细节),按照迭代器的方式遍历. 作用 Iterator模式是 ...

  3. 小笔记----about JC

    JC  project JAVA,Mysql. 页面用velocity template engine render的html/css Apache Velocity template engine ...

  4. 一、什么是Velocity及简单示例

    1.velocity简介:    velocity是一个java模板引擎技术,任何人可以使用这种简单而又强有力的模板语言去获取java对象. 在使用Velocity进行web开发时,web开发人员和j ...

  5. vue - 封装input

    input子组件 <el-input :value="value" placeholder="请输入内容" size="small" ...

  6. Maven项目- get请求的乱码问题,使用tamcat7出现乱码的解决方法

    get请求的乱码问题: 解决方法: 手动处理编码

  7. 「CF286C」Main Sequence

    传送门 Luogu 解题思路 看到正负号相互抵消,很容易联想到括号匹配和栈. 但由于题目钦定了一些位置只能是负数,所以我们可以这样考虑: 把负数视为右括号,正数视为左括号,然后开一个栈,从右往左遍历, ...

  8. Unity3d fbx纹理不显示 原因

    Unity3d 导入fbx文件后纹理不显示(3ds Max中显示正常) 原因: 1.纹理图片没有导入fbx同一文件夹中 2.纹理图片没有在fbx文件之前导入(现导入纹理图片,再导入fbx文件)

  9. 每个项目中,你必须知道的11个Java第三方类库。

    Java第三方library ecosystem是一个很广阔的范畴.不久前有人撰文:每个项目中,你必须知道的11个Java第三方类库. 单元测试 1.DBUnit DBunit是一个基于junit扩展 ...

  10. php 打印格式化显示利器 <pre>

    当我们PHP调试的时候,用var_dump 或 print_r打印json数据或array数组时,html页面没有换行显示,看到的内容一大堆,不好定位. 输出前添加 <pre>,便可以自动 ...