今天用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. 大数据萌新的Python学习之路(一)

    笔记开始简介 从2018年9月份正式进入大学的时代,大数据和人工智能的崛起让我选择了计算机专业学习数据科学与大数据技术专业,接触的第一门语言就是C语言,后来因为同学推荐的原因进入了学校的人工智能研究协 ...

  2. 本周总结(19年暑假)—— Part5

    日期:2019.8.11 博客期:111 星期日

  3. vue iviem UI grid布局

    Grid 栅格 概述 我们采用了24栅格系统,将区域进行24等分,这样可以轻松应对大部分布局问题.使用栅格系统进行网页布局,可以使页面排版美观.舒适. 我们定义了两个概念,行row和列col,具体使用 ...

  4. keil 生成bin文件

     在 User 配置页面中,提供了三种类型的用户指令输入框,在不同组的框输入指令,可控制指令的执行时间,分别是编译前(Before Compile c/c++ file).构建前(Before Bui ...

  5. jquery使用css函数设置背景色无效解决办法

    外部的css样式为: #imageArea{ width: 200px; height: 300px; background-color: #eee !important; } 通过 以下代码来修改其 ...

  6. ch4 背景图像基础

    如果希望网站有一个好看的背景,只需将背景应用于主体元素,即在body上应用background-image,默认情况下浏览器水平和垂直的重复显示背景图像,让图像平铺在整个页面上,可以选择背景图像是垂直 ...

  7. 「NOIP2015」运输计划

    传送门 Luogu 解题思路 首先这题可以直接二分答案,然后我们每次都把属于长度大于二分值的路径上的边标记一次,表示选这条边可以优化几条路径. 然后我们显然是要选一条覆盖次数等于需要覆盖的路径数并且长 ...

  8. 分页--pagination.js

    var pagination = function (thispage, totalpage, ulele, firstlast) { ulele.html(''); var prevCss, nex ...

  9. 070、Java面向对象之深入贯彻对象引用传递

    01.代码如下: package TIANPAN; class Book { // 定义一个新的类 String title; // 书的名字 double price; // 书的价格 public ...

  10. myeclipse中svn图标状态不显示问题的解决办法

    myeclipse中svn图标状态不显示问题的解决办法 博客分类: svn SVNMyeclipse工作WindowsC  myeclipse中使用 svn 插件,原本正常,未作任何更改,突然有一天, ...