方法一:
1、创建一个c语言项目。然后右键头文件,创建一个Stu的头文件。
2、然后编写头文件的代码。再将数据结构的增删改查和结构体写入头文件。
3、然后在源文件中创建main源文件和Stu源文件。再main文件中写入intmian()代码。
4、然后在mian主函数中,写入while语句无限循环。再写入Init函数。
5、在Stu源文件的Init函数用printf语句,将学生管理系统输出。再创建链表的头节点head。
6、然后用switch函数对 *** 作进行判断。再执行数据结构的增删改查功能。这样一个学生管理系统的基本框架就完成了。
方法二:
1、新建一个学生实体类,用于存放学生的各项信息。
2、新建一个链表节点类,每个节点存放一个学生信息及下一个节点的引用。
3、添加一个主 *** 作类,并添加本系统的菜单方法。
4、定义链表的头节点,当前最后一个节点,以及主控制逻辑信息。
5、使用io流逐行读取存有学生信息的文本文件,对每行字符串,采用\t分割后得到一个字符串数组,数据各项即为一个学生的具体信息。然后新建一个节点加入到链表。
6、运行结果:
代码如下:
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
typedef struct examinee //考生信息结构
{ char examno[20]//准考证号
char name[10]//姓名
char sex[4]//性别
short age//年龄
char examtype[10]//报考科目
}ElemType
typedef struct Node //定义链表结点
{
ElemType data//数据域
struct Node *next//指针域
}Node,*List,*position
List make_empty( List L )//创建一个带头结点的空表
int is_empty( List L )//测试链表是否是空表
int is_last( position p, List L )//测试当前位置是否是表尾
position make_node( position p,int n )//创建结点并输入考生信息
void put_information( position p )//是否输出该考生信息
void put_name_information( List L )//输出姓名为xx的考生信息
int put_pos_information( position p )//输出该地址考生信息
void link_to_tail( List L, position p )//将结点连接到表尾
int ciculation_make()//循环创建考生信息
int judge_put_all()//是否输出所有考生信息
void put_all(List L)//输出所有考生信息。
position find( List L )//查找第一个姓名为xx的元素并返回位置
position find_previous( List L )//查找第一个姓名为xx的元素并返回该元素直接前驱的位置
//int judge_delete_val()//询问是否删除考生数据
int delete_val( List L )//删除指定考生信息并输出其信息
void menu(List L)//菜单函数
List L
//position p
int
main( void )
{
List L = NULL//定义头结点指针
position p = NULL//定义表工作指针
L = make_empty( L )//创建空表
printf("\t\t\t★★考生报名管理程序★★\n\t\t----------------------------------------\n")
menu(L)
return 0
}
//创建一个带头结点的空表
List
make_empty( List L)
{
L = ( List ) malloc (sizeof( Node ))
if(NULL == L)
{
printf("内存分配失败")
exit( 1 )
}
L->next = NULL
//printf("空表创建成功。\n")
return L
}
//创建结点并输入考生信息
position
make_node( position p ,int n)
{
if(n) //n为1是创建结点并输入,n为0是修改
{
p = ( position ) malloc ( sizeof ( Node ))
p->next = NULL
}
printf("请输入考生准考证号:")
gets(p->data.examno)
printf("请输入考生姓名:")
gets(p->data.name)
do
{
printf("请输入考生性别,只能输入“男”或者“女”:")
gets(p->data.sex)
}
while( 0 != strcmp( p->data.sex, "男" ) &&0 != strcmp( p->data.sex, "女" ))//判断性别是否有误
printf("请输入考生年龄:")
scanf("%hd",&p->data.age)
getchar() //如果把这句删掉,就“无法执行”下面的报考类别
/*下面的do while用来判断报考类别是否输入有误*/
do
{
printf("请输入报考类别,只能输入“数学”或“英语”或者“数据结构”:")
gets(p->data.examtype)
}
while( 0 != strcmp( "英语", p->data.examtype ) &&0 != strcmp( "数学", p->data.examtype ) &&0 != strcmp( "数据结构", p->data.examtype ))
if(n)
{
printf("报名成功\n")
}
else
{
printf("修改成功\n")
}
return p
}
//前插法;
void
link_to_tail( List L, position p)
{
p->next = L->next
L->next = p
}
//查找第一个姓名为xx的元素并返回位置
position
find( List L )
{
position p = L->next
char name[10]
printf("请输入你要查找的考生姓名:")
gets(name)
while( p != NULL &&0 != strcmp( p->data.name , name))
{
p=p->next
}
return p
}
//测试链表是否是空表
int
is_empty( List L )
{
return L->next == NULL
}
//测试当前位置是否是表尾
int
is_last( position p, List L )
{
return p->next == NULL
}
//输出姓名为xx的考生信息
void
put_name_information( List L )
{
position p = find(L)
if(p!=NULL)
{
printf("您要查找的考生信息:\n")
printf("准考证号:%s\t姓名:%s\t性别:%s\t年龄:%hd\t报考科目:%s\n\n",p->data.examno,p->data.name,p->data.sex,p->data.age,p->data.examtype)
}
else
{
printf("没有您要找的学生。\n")
}
}
//循环创建考生信息
int
ciculation_make()
{
int n = 2
do
{
printf("是否继续创建考生信息?是请输入“1”,不是请输入“0”:")
scanf("%d",&n)
getchar()
}
while( n != 0 &&n != 1)
return n
}
//是否输出考生信息
void
put_information( position p )
{
int n=2
do
{
printf("是否输出该考生信息?是请输入“1”,不是请输入“0”:")
scanf("%d",&n)
getchar()
}
while( n != 0 &&n != 1)
if(n)
{
printf("准考证号:%s\t姓名:%s\t性别:%s\t年龄:%hd\t报考科目:%s\n",p->data.examno,p->data.name,p->data.sex,p->data.age,p->data.examtype)
}
}
//是否输出所有考生信息
int
judge_put_all()
{
int n = 2
do
{
printf("是否输出所有考生信息?是请输入“1”,不是请输入“0”:")
scanf("%d",&n)
getchar()
}
while( n != 0 &&n != 1)
return n
}
//输出所有考生信息
void
put_all(List L)
{
if(L->next == NULL)
{
printf("现无考生报名!\n")
}
else
{
position p=L->next
while( p != NULL )
{
printf("准考证号:%s\t姓名:%s\t性别:%s\t年龄:%hd\t报考科目:%s\n",p->data.examno,p->data.name,p->data.sex,p->data.age,p->data.examtype)
p=p->next
}
}
//getchar()
}
//询问是否删除考生数据
int
judge_delete_val()
{
int n = 2
do
{
printf("是否要删除某个考生数据?是请输入“1”,不是输入“0”:")
scanf("%d",&n)
getchar()
}
while( n != 0 &&n != 1)
return n
}
//查找第一个姓名为xx的元素并返回其直接前驱的位置
position
find_previous( List L )
{
position q = L
position p = L->next
char name[10]
printf("请输入你要查找的考生姓名:")
gets(name)
while( p != NULL &&0 != strcmp( p->data.name , name))
{
q=p
p=p->next
}
if( p != NULL )
{
return q
}
else
return p
}
//删除指定考生信息并输出其信息
int
delete_val(List L)
{
int n=2
position q=NULL
position p=find_previous( L )//返回考生信息地址
if( NULL == p )
{
printf("你要删除的考生不存在\n")
return 0
}
else
{
q = p->next
p->next = q->next
printf("删除成功。\n删除的考生信息为:\n")
printf("准考证号:%s\t姓名:%s\t性别:%s\t年龄:%hd\t报考科目:%s\n",q->data.examno,q->data.name,q->data.sex,q->data.age,q->data.examtype)
free(q)
return 1
}
}
//输出该地址考试信息
int
put_pos_information( position p )
{
if(p != NULL )
{
printf("准考证号:%s\t姓名:%s\t性别:%s\t年龄:%hd\t报考科目:%s\n\n",p->data.examno,p->data.name,p->data.sex,p->data.age,p->data.examtype)
return 1
}
else
{
printf("没有您要查找的学生。")
return 0
}
}
//菜单函数
void
menu(List L)
{
printf("\t\t\t a. 考生报名入口\n")
printf("\t\t\t b. 查询考生信息\n")
printf("\t\t\t c. 修改考生信息\n")
printf("\t\t\t d. 删除考生信息\n")
printf("\t\t\t e. 全部考生信息\n")
printf("\t\t\t f. 程序作者信息\n")
printf("\t\t\t g. 退出程序\n")
char n='h'
while(n != 'g')
{
do //确定正确输入
{
printf("请通过字母序号选择功能:")
n = getchar()
getchar()
putchar('\n')
if( n <'a' || n >'g')
{
printf("错误的字母序号。\n")
}
}
while( n <'a' || n >'g' )
switch (n)
{
case 'a':
{
printf("请输入报名考生信息:\n")
position p = make_node( p, 1 )//创建新结点
link_to_tail( L, p )//将新结点连接到表上
put_information( p ) //是否输出该考生信息
putchar('\n')
}
break
case 'b':
{
put_name_information( L )
putchar('\n')
}
break
case 'c':
{
int n=0
position p = NULL
printf("您正在进行修改 *** 作。\n")
p = find(L)
n = put_pos_information( p )
if(n)
{
make_node( p , 0 )
put_information( p ) //是否输出该考生信息
}
putchar('\n')
}
break
case 'd':
{
printf("您正在进行删除 *** 作。\n")
delete_val( L )
putchar('\n')
}
break
case 'e':
{
put_all( L )
putchar('\n')
}
break
case 'f':
{
printf(" 修改日期 版本号 修改人 修改内容 \n")
printf(" --------------------------------------------------------\n")
printf(" 2018.6.19 v2.0 陈百川 增加主菜单\n")
printf(" 2018.6.23 v3.0 陈百川 增加生成文件功能\n\n")
printf(" 该版本号为v2.0\n")
putchar('\n')
}
break
default:
break
}
}
printf(" 感谢本次使用,祝您生活愉快。")
getch()
}
扩展资料:
C语言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。
尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式处理器(单片机或称MCU)以及超级电脑等作业平台。
二十世纪八十年代,为了避免各开发厂商用的C语言语法产生差异,由美国国家标准局为C语言制定了一套完整的美国国家标准语法,称为ANSI C,作为C语言最初的标准。[1] 目前2011年12月8日,国际标准化组织(ISO)和国际电工委员会(IEC)发布的C11标准是C语言的第三个官方标准,也是C语言的最新标准,该标准更好的支持了汉字函数名和汉字标识符,一定程度上实现了汉字编程。
C语言是一门面向过程的计算机编程语言,与C++,Java等面向对象的编程语言有所不同。
其编译器主要有Clang、GCC、WIN-TC、SUBLIME、MSVC、Turbo C等。
参考资料:百度百科——C语言
数据库连接(Connection)数据库连接
获取数据库连接有两种方法,一种是通过驱动程序管理器DriverManager类,另一种则是使用DataSource接口。这两种方法都提供了了一个getConnection方法,用户可以在程序中对它们进行相应处理后调用这个方法来返回数据库连接。
• DriverManager类
• DataSource接口
• Connection接口
• JDBC URL
jdbc:<subprotocol>:<subname>
• 驱动程序注册方法
(1)调用Class.forName方法
(2)设置jdbc.drivers系统属性
• DriverManager方法
DriverManager类中的所有方法都是静态方法,所以使用DriverManager类的方法时,不必生成实例。
DriverManager
• getConnection方法
作用是用于获取数据库连接,原型如下:
public static Connection getConnection(String url)
throws SQLException;
public static Connection getConnection(String url, String user, String password)
throws SQLException
public static Connection getConnection(String url, Properties info)
throws SQLException
• 使用DriverManager的getConnetion方法
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver")
Connection conn = DriverManager.getConnection
("jdbc:odbc:sqlserver", "sa", "sa")
• 使用设置jdbc.drivers系统属性的方法
java -Djdbc.drivers=sun.jdbc.odbc.JdbcOdbcDriver test.java
DataSource 接口
……
//从上下文中查找数据源,并获取数据库连接
Context ctx = new InitialContext()
DataSource ds = (DataSource) ctx.lookup("sqlserver")
Connection conn = ds.getConnection()
//查询数据库中所有记录
Statement stmt = conn.createStatement()
ResultSet rs = stmt.executeQuery("SELECT * FROM student")
……
Connection 接口
Connection接口代表了已经建立的数据库连接,它是整个JDBC的核心内容。Connnection接口中的方法按照它们所实现的功能,可以分为三类:
• 生成数据库语句
• 管理数据库事务
• 获取数据库信息
生成数据库语句
JDBC将数据库语句分成三种类型 :
• 生成Statement 语句 :
Connection.createStatement()
• 生成PreparedStatement 语句 :
Connection. prepareStatement()
• 生成CallableStatement 语句 :
Connection. prepareCall ()
管理数据库事务
• 默认情况下,JDBC将一条数据库语句视为一个完整的事务。可以关掉默认事务管理:
public void setAutoCommit(Boolean autoCommit) throws SQLException;
将autoCommit的值设置为false,就关掉了自动事务管理模式
• 在执行完事务后,应提交事务:
public void commit() throws SQLException;
• 可以取消事务:
public void rollback() throws SQLException;
第二讲 第四部分
数据库语句
数据库语句
JDBC数据库语句共有三种类型:
• Statement:
Statement语句主要用于嵌入一般的SQL语句,包括查询、更新、插入和删除等等。
• PreparedStatement:
PreparedStatement语句称为准备语句,它是将SQL语句中的某些参数暂不指定,而等到执行时在统一指定。
• CallableStatement:
CallableStatement用于执行数据库的存储过程。
Statement 语句
• executeQuery方法
• executeUpdate方法
• execute方法
• close方法
executeQuery方法
• executeQuery方法主要用于执行产生单个结果集的SQL查询语句(QL),即SELECT语句。executeQuery方法的原型如下所示:
• public ResultSet executeQuery(String sql) throws SQLException
executeUpdate方法
• executeUpdate方法主要用于执行 INSERT、UPDATE、DELETE语句,即SQL的数据 *** 作语句(DML)
• executeUpdate方法也可以执行类似于CREATE TABLE和DROP TABLE语句的SQL数据定义语言(DDL)语句
• executeUpdate方法的返回值是一个整数,指示受影响的行数(即更新计数)。而对于CREATE TABLE 或 DROP TABLE等并不 *** 作特定行的语句,executeUpdate的返回值总为零。
execute方法
execute方法用于执行:
• 返回多个结果集
• 多个更新计数
• 或二者组合的语句
execute方法
• 返回多个结果集:首先要调用getResultSet方法获得第一个结果集,然后调用适当的getter方法获取其中的值。要获得第二个结果集,需要先调用getMoreResults方法,然后再调用getResultSet方法。
• 返回多个更新计数:首先要调用getUpdateCount方法获得第一更新计数。然后调用getMoreResults,并再次调用getUpdateCount获得后面的更新计数。
• 不知道返回内容:如果结果是ResultSet对象,则execute方法返回true;如果结果是int类型,则意味着结果是更新计数或执行的语句是DDL命令。
execute方法
为了说明如果处理execute方法返回的结果,下面举一个代码例子:
stmt.execute(query)
while (true) {
int row = stmt.getUpdateCount()
//如果是更新计数
if (row >0) {
System.out.println("更新的行数是:" + row)
stmt.getMoreResults()
continue
}
execute方法
//如果是DDL命令或0个更新
if (row == 0) {
System.out.println("没有更新,或SQL语句是一条DDL语句!")
stmt.getMoreResults()
continue
}
//如果是一个结果集
ResultSet rs = stmt.getResultSet
if (rs != null) {
while (rs.next()) {
// 处理结果集
. . .
}
stmt.getMoreResults()
continue
}
break
}
PreparedStatement 语句
登录一个网站或BBS时 :
• 使用Statement语句
Statement stmt = conn.createStatement()
ResultSet rs = stmt.executeQuery
(“SELECT password FROM userinfo
WHERE id=userId")
• 使用PreparedStatement语句
PreparedStatement pstmt=conn.prepareStatement
(“SELECT password FROM userinfo
WHERE id=?")
pstmt.setString(1, userId)
PreparedStatement语句
• 常用的setter方法
public void setBoolean(int parameterIndex, boolean x) throws SQLException
public void setByte(int parameterIndex, byte x) throws SQLException
public void setShort(int parameterIndex, short x) throws SQLException
public void setInt(int parameterIndex,int x) throws SQLException
public void setLong(int parameterIndex, long x) throws SQLException
public void setFloat(int parameterIndex, float x) throws SQLException
public void setDouble(int parameterIndex, double x) throws SQLException
public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException
public void setString(int parameterIndex, String x) throws SQLException
public void setBytes(int parameterIndex, byte[] x) throws SQLException
public void setDate(int parameterIndex, Date x) throws SQLException
public void setTime(int parameterIndex, Time x) hrows SQLException
public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException
PreparedStatement语句
• PreparedStatement接口是由Statement接口扩展而来的,重写了executeQuery方法、executeUpdate方法和execute 方法
• public ResultSet executeQuery() throws SQLException
• public int executeUpdate() throws SQLException
• public boolean execute() throws SQLException
CallableStatement语句
• CallableStatement语句是由Connection接口的prepareCall方法创建的,创建时需要传入字符串参数,参数的形式为:
• {call procedure_name[(?, ?, ...)]}
• {? = call procedure_name[(?, ?, ...)]}
• {call procedure_name}
CallableStatement语句
• 其中的问号是参数占位符,参数共有两种:
• IN参数
• OUT参数
• IN参数使用setter方法来设置
• OUT参数则使用registerOutParameter方法来设置
CallableStatement 语句
CallableStatement cstmt = con.prepareCall
("{call getTestData(?, ?)}")
cstmt.registerOutParameter
(1, java.sql.Types.TINYINT)
cstmt.registerOutParameter
(2, java.sql.Types.DECIMAL, 3)
cstmt.executeQuery()
byte x = cstmt.getByte(1)
java.math.BigDecimal n =
cstmt.getBigDecimal(2, 3)
第二讲 第五部分
结 果 集
结果集
• JDBC为了方便处理查询结果,又专门定义了一个接口,这个接口就是ResultSet接口。ResultSet接口提供了可以访问数据库查询结果的方法,通常称这个接口所指向的对象为结果集。
• 有两种方法得到结果集,一种是直接执行查询语句,将结果存储在结果集对象上;另一种是不存储返回结果,而在需要时调用数据库语句的getResultSet方法来返回结果集
结果集
• 结果集指针
由于返回的结果集可能包含多条数据记录,因此ResultSet 接口提供了对结果集的所有数据记录轮询的方法。结果集自动维护了一个指向当前数据记录的指针,初始时这个指针是指向第一行的前一个位置。 next 方法就是用于向前移动指针的
结果集
• 结果集属性
默认情况下,结果集是一个不可更新集,并且结果集的指针也只能向前移动。也就是说,在得到了一个结果集之后,用户只能按照从第一条记录到最后一条记录的顺序依次向后读取,而不能跳到任意条记录上,也不能返回到前面的记录。不仅如此,结果集的这种轮询只能进行一次,而不能再将指针重置到初始位置进行多次轮询
结果集
• 结果集属性
类型
并发性
有效性
• 属性的设置是在生成数据库语句时通过向生成方法传入相应的参数设定的,而当结果集已经返回时就不能够再改变它的属性了。
结果集生成Statement语句共有三种方法
public Statement createStatement() throws SQLException
public Statement createStatement
(int resultSetType, int resultSetConcurrency)
throws SQLException
public Statement createStatement
(int resultSetType, int resultSetConcurrency,
int resultSetHoldability)
throws SQLException
结果集
• 生成PreparedStatement语句共有六种方法
public PreparedStatement prepareStatement(String sql) throws SQLException
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
throws SQLException
public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
throws SQLException
public PreparedStatement prepareStatement(String sql, int resultSetType,
int resultSetConcurrency)
throws SQLException
public PreparedStatement prepareStatement(String sql, int resultSetType,
int resultSetConcurrency,
int resultSetHoldability)
throws SQLException
public PreparedStatement prepareStatement(String sql. String[] columnNames)
throws SQLException
结果集
• 生成CallableStatement语句共有三种方法
public CallableStatement prepareCall(String sql)
throws SQLException
public CallableStatement prepareCall
(String sql, int resultSetType,
int resultSetConcurrency)
throws SQLException
public CallableStatement prepareCall
(String sql, int resultSetType,
int resultSetConcurrency,
int resultSetHoldability)
throws SQLException
结果集
结果集类型
• 结果集的类型共有三种,TYPE_FORWARD_ONLY类型的结果集只能向前移动指针,而TYPE_SCROLL_INSENSITIVE类型和TYPE_SCROLL_SENSITIVE类型的结果集则可以任意移动指针。后两种类型的区别在于,前者对来自其它处的修改不敏感(静态),而后者则对于别人的修改敏感(动态视图)。
结果集
结果集类型
• 对于可以任意移动指针的结果集,可以用来移动指针的方法包括:
• next 和previous :
• absolute 和relative :参数可正可负
• afterLast 、beforeFirst 、last 和first :
结果集
结果集并发性
• 结果集的并发性共有两种,CONCUR_READ_ONLY的结果集是只读而不可更新的;而CONCUR_UPDATABLE的结果集则是可以通过update方法进行更新的。
• ResultSet接口提供了一组update方法,用于更新结果集中的数据。这些方法与PreparedStatement接口中定义的setter方法一样,也是与类型相对应的。所有的update方法都以update开头 。
• 所有的update方法都有两个参数,第一个参数用于指定更新的列,它可以是列名称也可以是列的序号;第二个参数则表示将要更新列的值。
结果集
结果集并发性
• Statement stmt = conn.createStatement
•(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)
•ResultSet rs = stmt.executeQuery("SELECT * FROM student " +
• "WHERE grade=2 AND math>60 AND physics>60 AND " +
• "chemistry>60 AND english>60 AND chinese>60")
•while(rs.next()){
•rs.updateString("grade", "3")
•rs.updateRow()
•}
结果集
结果集有效性
• 结果集的有效性是指在调用了Connection 接口的commit 方法后,结果集是否自动关闭。所以它只有两个可选值,即HOLD_CURSORS_OVER_COMMIT 和CLOSE_CURSORS_AT_COMMIT 。前者表示调用commit 方法之后,结果集不关闭;而后者则表示关闭结果集。
结果结果集
• 结果集的getter方法
ResultSet接口还提供了一组getter方法,用于返回当前记录的属性值。它们都是以get开头的,后接数据类型。比如,如果要返回一个float类型的列值,则应调用getFloat方法。每一种类型的getter方法都有两种形式,它们的名称相同而参数不同。这两种形式的getter方法都只有一个参数,第一种形式的getter方法参数是String类型的,用于指定列的名称;另外一种形式的getter方法参数则是int类型的,用于指定列的序号。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)