linux退格键处理

//mydb.h
#ifndef MYDB_H_
#define MYDB_H_ void init_db(); int conn_db(const char *hostname, const char *username, const char *password, const char *dbname); void disconn_db(); int open_db(const char *SQL); int exec_db(const char *SQL); #endif /* MYDB_H_ */
//mydb.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <mysql/mysql.h> #include "mydb.h" MYSQL *connection = NULL; MYSQL mysql; void init_db() { mysql_init(&mysql);//初始化mysql } int conn_db(const char *hostname, const char *username, const char *password, const char *dbname) { if (connection) mysql_close(connection); connection = mysql_real_connect(&mysql, hostname, username, password, dbname, 0, 0, 0);//连接到mysql if (connection == NULL) { printf("%s\n", mysql_error(&mysql)); return -1;//连接失败,返回-1 } printf("success connect to mysql\n"); return 0; } void disconn_db()//断开数据库连接 { if (connection) { mysql_close(connection); connection = NULL; } } int open_db(const char *SQL)//执行有返回数据集的SQL语句 { int state = mysql_query(connection, SQL);//执行SQL语句 if (state != 0) { printf("%s\n", mysql_error(connection)); return -1;//执行失败,返回-1 } MYSQL_RES *result = mysql_store_result(connection);//得到查询结果 if (result == (MYSQL_RES *) NULL) { printf("%s\n", mysql_error(connection)); return -1;//执行失败,返回-1 } else { MYSQL_FIELD *sqlField; int iFieldCount = 0; while (1)//循环遍历所有字段 { sqlField = mysql_fetch_field(result); if (sqlField == NULL) break; printf("%s\t", sqlField->name);//向屏幕打印字段名 iFieldCount++; } printf("\n");//每一行结尾打印一个\n字符 MYSQL_ROW sqlRow; while (1)//循环到每一行 { sqlRow = mysql_fetch_row(result); if (sqlRow == NULL) break; int i; for (i = 0; i < iFieldCount; i++)//循环得到每一行中的每个字段 { if (sqlRow[i] == NULL) printf("NULL\t");//如果值为NULL,屏幕打印为"NULL" else printf("%s\t", (const char *)sqlRow[i]);//屏幕打印为字段内容 } printf("\n");//每一行结尾打印一个\n字符 } printf("query is ok, %u rows affected\n", (unsigned int)mysql_affected_rows(connection)); mysql_free_result(result); } return 0; } int exec_db(const char *SQL)//执行没有返回数据集的SQL语句 { int state = mysql_query(connection, SQL);//执行SQL语句 if (state != 0) { printf("%s\n", mysql_error(connection)); return -1; } printf("query is ok, %u rows affected\n", (unsigned int)mysql_affected_rows(connection)); return 0; }
//mysql1.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <termios.h>
#include "mydb.h"


void sqldb(const char *src)//参数src为要执行的SQL语句
{
    if ((strncmp(src, "select", 6) == 0) || (strncmp(src, "SELECT", 6) == 0)
            || (strncmp(src, "show", 4) == 0) || (strncmp(src, "SHOW", 4) == 0)
            || (strncmp(src, "desc", 4) == 0) || (strncmp(src, "DESC", 4) == 0))
    {
        open_db(src);//如果src为有返回数据集SQL语句,那么调用open_db函数
    } else
    {
        exec_db(src);//如果src为没有有返回数据集SQL语句,那么调用exec_db函数
    }
}



void work(const char *userid, const char *password)
{
    init_db();
    if (conn_db("localhost", userid, password, "test") != 0)//连接到数据库
    {
        return;//连接数据库失败,函数退出
    }
    char buf[2048];
    while (1)//循环从键盘读取
    {
        write(STDOUT_FILENO, "mysql1>", strlen("mysql1>"));//屏幕输出命令提示符mysql1>
        memset(buf, 0, sizeof(buf));
        read(STDIN_FILENO, buf, sizeof(buf));//等待用户从键盘输入
        if (strncmp(buf, "quit", 4) == 0)
            break;//用户输入quit,循环break;
        sqldb(buf);
    }
    disconn_db();//断开数据库连接
}


struct termios oldterm;
void setstty()//设置输入退格键,不回显
{
    //system("stty erase ^H");//执行shell命令,也可以 用来设置读取用户键盘输入的时候,退格键不回显
    struct termios term;
    if(tcgetattr(STDIN_FILENO, &term) == -1)//得到系统termion的设置
    {
        printf("tcgetattr error is %s\n", strerror(errno));
        return;
    }

    oldterm = term;//保留当前termios设置,以便程序退出的时候可以恢复termios

    /*
    term.c_lflag &= ~ICANON;//取消ICANON选项(不规范输入)
    term.c_lflag |= ICANON;//设置ICANON选项(规范输入)
    term.c_cc字段为要设置的具体特殊输入字符,如c_cc[VERASE]代表退格键,
    term.c_cc[VERASE] = '\b';意思为把退格键修改为'\b'
    VERASE代表向前擦出一个字符,VINTR代表发送ctrl + C中断信号,ctrl + c的ASCII码为3
    例如:term.c_cc[VINTR] = '\t';意思为将tab键设置为终端信号
    tcsetattr中,第二个参数说明,TCSAFLUSH:发送了所有输出后更改才生效,在更改发生时,未读取的所有输入数据都被删除
    TCSANOW:更改立即生效
    TCSADRAIN:发送了所有输出后更改才发生,如果更改输出参数则应该使用该选项
    */
    term.c_cc[VERASE] = '\b';//'\b'为退格键的ASCII码
    if (tcsetattr(STDIN_FILENO, TCSANOW, &term) == -1)//设置系统termion
    {
        printf("tcsetattr error is %s\n", strerror(errno));
    }
    return;
}

void returnstty()//恢复系统的termios设置
{
    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &oldterm) == -1)//设置系统termion
    {
        printf("tcsetattr error is %s\n", strerror(errno));
    }
    return;
}


int main(int arg, char *args[])
{
    if (arg < 4)//如果没有参数,main函数退出
    {
        return EXIT_FAILURE;
    }

    if (strncmp(args[1], "-u", 2) != 0)//如果第二个参数不是-u,main函数退出
    {
        return EXIT_FAILURE;
    }

    if (strncmp(args[3], "-p", 2) != 0)//如果第四个参数不是-p,main函数退出
    {
        return EXIT_FAILURE;
    }

    const char *passwd = getpass("please input password:");//输入密码,屏幕不回显

    setstty();//设置输入退格键,不回显
    work(args[2], passwd);
    returnstty();//恢复系统的termios设置
    return EXIT_SUCCESS;
}

 

posted @ 2015-05-05 10:33  禅意  阅读(1190)  评论(0编辑  收藏  举报