C调用webservice制作航班查询功能

一直以来,我对C语言充满敬畏,毕竟C语言如同“造物主”般的存在,不少流行的编程语言、数据库等都是由C语言编写出来的,一直梦想自己是使用C语言的高手。记得读书时教C语言的老师曾经说过:“计算机世界里,万物皆C,没学过C语言是一种莫大的遗憾”。
毕业参加工作了,虽然不使用C语言开发,心里总有那么一点小遗憾。因此闲暇时就会用C语言去实现一些功能,毕竟C语言没那么多包,很多时候都需要靠自己编写。
本次使用C调用webservice实现了航班查询的功能,大致总结如下:
1、使用开放的webservice接口
2、返回i的数据保存到mariadb数据库中
3、具备日志记录功能,可以记录返回报文、解析数据日志等
4、由于没搞定gsoap和libxml2,因此调用webservice引用了shell命令curl,解析xml时就是采用普通的文件读取方式。换言之,该功能在linux下使用,如fedora31
5、编写过程中,C语言处理字符串真的好忧伤,极其怀念Java,Go,Python对字符串的处理
6、光学会C还没法正常实现,还必须熟练系统。只有熟练系统了才知道如何加载必要的包,比如连接mariadb的h文件
代码如下:
头文件airline.h
// An highlighted block
#include <mysql/mysql.h>
#ifndef AIRLINESCHEDULE_AIRLINE_H
#define AIRLINESCHEDULE_AIRLINE_H
void str_replace(char* cp,int n,char* str);
int produce_time(char* current_time);
void get_regular_data(char* file_name,char* start_city,char* arrive_city,char* query_date);
char *a_trim(char *str);
void save_airline_info(char* text_file,char* start_city,char* arrive_city,char* query_date);
MYSQL con_mariadb();
void close_mariadb_con(MYSQL *con);
void close_mariadb_result(MYSQL_ROW row);

#endif //AIRLINESCHEDULE_AIRLINE_H
// main
main函数
// An highlighted block
/*
 * 程序目的:C和bash联合使用通过webservice获取航班信息
 * 程序版本:C99 and Bash5.0
 * 程序编写:枫叶
 * 编写时间:2020年3月17日
 */
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "head/airline.h"

int main()
{
    printf("----------航班查询系统---------\n");
    //构造文件名并创建文件
    char nowTime[32] = {0};
    produce_time(nowTime);
    char file_head[] = "airline";
    char file_suffix[] = ".xml";
    char* file_name;
    file_name = strcat(strcat(file_head,nowTime),file_suffix);
    FILE *fp_write = fopen(file_name,"a");
    //printf("fileName is:%s\n",file_name);
    //构造文件名
    //printf("current time is:%s\n",nowTime);
    //定义查询参数和执行的命令
    char start_city[] = "桂林";
    char arrive_city[] = "杭州";
    char query_date[] = "2020-3-24";
    char command[] = "curl -d \"startCity=${start_city}&lastCity=${arrive_city}&theDate=${query_date}&userID=\" http://ws.webxml.com.cn/webservices/DomesticAirline.asmx/getDomesticAirlinesTime";
    //定义查询参数和执行的命令
    //定义要替换的字符串
    char s_city[] = "${start_city}";
    char a_city[] = "${arrive_city}";
    char q_date[] = "${query_date}";
    char* p;
    int counter = 0;
    //定义要替换的字符串
    //替换起飞城市
    p = strstr(command,s_city);
    while(p)
    {
        counter++;
        str_replace(p,strlen(s_city),start_city);
        p = p+strlen(start_city);
        p = strstr(p,s_city);
    }
    //替换抵达城市
    p = strstr(command,a_city);
    counter = 0;
    while(p)
    {
        counter++;
        str_replace(p,strlen(a_city),arrive_city);
        p = p+strlen(arrive_city);
        p = strstr(p,a_city);
    }
    //替换查询日期
    p = strstr(command,q_date);
    counter = 0;
    while(p)
    {
        counter++;
        str_replace(p,strlen(q_date),query_date);
        p = p+strlen(query_date);
        p = strstr(p,q_date);
    }
    //printf("%s\n",command);
    //printf("----------%s %s至%s航班信息----------\n",query_date,start_city,arrive_city);
    //调用shell命令进行webservice操作
    FILE *fp;
    int buf;
    fp = popen(command,"r");
    buf = fgetc(fp);
    fputc(buf,fp_write);
    while(buf != EOF)
    {
        putchar(buf);
        buf = fgetc(fp);
        fputc(buf, fp_write);
    }

    //printf("%c\n",buf);
    fclose(fp);
    printf("关闭webservice连接...\n");
    fclose(fp_write);
    printf("保存并关闭%s...\n",file_name);
    get_regular_data(file_name,start_city,arrive_city,query_date);
    return 0;
}

// get_current_time
get_current_time函数
// An highlighted block
/*
 * 程序目的:获取当前时间
 * 程序版本:C99
 * 程序编写:枫叶
 * 编写时间:2020年3月17日
 */
#include <time.h>
#include <string.h>

int produce_time(char* current_time)
{
    char year[5] = {0};
    char month[5] = {0};
    char day[5] = {0};
    char hour[5] = {0};
    char min[5] = {0};
    char second[5] = {0};
    time_t current;
    struct tm* time_now;
    time(&current);
    time_now = localtime(&current);
    strftime(year,sizeof(year),"%Y",time_now);
    strftime(month,sizeof(month),"%m",time_now);
    strftime(day,sizeof(day),"%d",time_now);
    strftime(hour,sizeof(hour),"%H",time_now);
    strftime(min,sizeof(min),"%M",time_now);
    strftime(second,sizeof(second),"%S",time_now);
    strncat(current_time, year, 4);
    strncat(current_time, month, 2);
    strncat(current_time, day, 2);
    strncat(current_time, hour, 2);
    strncat(current_time, min, 2);
    strncat(current_time, second, 2);

    return 0;
}
// strsubstitute
strsubstitute
// An highlighted block
/*
 * 程序目的:将字符串中属于参数的部分进行替换
 * 程序版本:C99
 * 程序编写:枫叶
 * 编写时间:2020年3月17日
 */
#include <string.h>
#include <ctype.h>
//字符串替换,将查询字段替换成相应的入参参数
void str_replace(char* cp,int n,char* str)
{
    int len_str = strlen(str);
    char* tmp;
    if(len_str<n)
    {
        tmp = cp+n;
        while(*tmp)
        {
            *(tmp-(n-len_str)) = *tmp;
            tmp++;
        }
        *(tmp-(n-len_str)) = *tmp;
    }
    else
    {
        if(len_str>n)
        {
            tmp = cp;
            while(*tmp) tmp++;
            while(tmp>=cp+n)
            {
                *(tmp+len_str-n) = *tmp;
                tmp--;
            }
        }
    }
    strncpy(cp,str,len_str);
}

//去除字符串中的空格函数矩阵
//去除右空格
char *r_trim(char *str)
{
    if(str==NULL || *str=='\0')
    {
        return str;
    }
    int len = strlen(str);
    char *p = str+len-1;
    while(p>=str && isspace(*p))
    {
        *p = '\0';
        --p;
    }
    return str;
}
//去除左空格
char *l_trim(char *str)
{
    if(str==NULL || *str=='\0')
    {
        return str;
    }
    int len = 0;
    char *p = str;
    while(*p!='\0' && isspace(*p))
    {
        ++p;
        ++len;
    }
    memmove(str, p, strlen(str) - len + 1);
    return str;
}
//去除所有空格
char *a_trim(char *str)
{
    str = r_trim(str);
    str = l_trim(str);
    return str;
}
// regular_data
regular_data函数
// An highlighted block
/*
 * 程序目的:解析XML并将解析好的数据记录到临时文件
 * 程序版本:C99
 * 程序编写:枫叶
 * 编写时间:2020年3月17日
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "../head/airline.h"

//解析xml中的数据并插入数据库表
void get_regular_data(char* file_name,char* start_city,char* arrive_city,char* query_date)
{
    FILE *fp;
    //根据xml节点定义查找内容
    char company[] = "";
    char airline_code[] = "";
    char start_drome[] = "";
    char arrive_drome[] = "";
    char start_time[] = "";
    char arrive_time[] = "";
    char air_mode[] = "";
    char air_stop[] = "";
    char cycle[] = "";
    //根据xml节点定义查找内容
    //定义要替换的字符串
    char* p;
    char after[] = "";
    char s_company[] = "";
    char s_airline_code[] = "";
    char s_start_drome[] = "";
    char s_arrive_drome[] = "";
    char s_start_time[] = "";
    char s_arrive_time[] = "";
    char s_air_mode[] = "";
    char s_air_stop[] = "";
    char s_cycle[] = "";
    //定义要替换的字符串
    char file_str[1024];
    //将分解的信息记录到临时文件,以便插入数据库用
    char file_head[] = "insert_data";
    char file_suffix[] = ".txt";
    char c_time[32] = {0};
    produce_time(c_time);
    char* tmp_file_name;
    tmp_file_name = strcat(strcat(file_head,c_time),file_suffix);
    char text_file[] = {0};
    strcpy(text_file,tmp_file_name);
    //printf("save file name is:%s\n",text_file);
    //printf("create file name is:%s\n",tmp_file_name);
    FILE *fp_write = fopen(tmp_file_name,"a");
    //将分解的信息记录到临时文件,以便插入数据库用
    printf("----------%s %s至%s航班信息----------\n",query_date,start_city,arrive_city);
    fp = fopen(file_name,"r");
    if(fp == NULL)
    {
        printf("Can not open the file!\n");
        exit(1);
    }
    while(fgets(file_str, sizeof(file_str),fp))
    {

        if(strstr(file_str,company))
        {
            p = strstr(file_str,company);
            str_replace(p,strlen(company),after);
            p = strstr(file_str,s_company);
            str_replace(p,strlen(s_company),after);
            fputs(a_trim(file_str),fp_write);
            fputs("|",fp_write);
            //printf("%s\n",file_str);
        }
        else if (strstr(file_str,airline_code))
        {

            p = strstr(file_str,airline_code);
            str_replace(p,strlen(airline_code),after);
            p = strstr(file_str,s_airline_code);
            str_replace(p,strlen(s_airline_code),after);
            fputs(a_trim(file_str),fp_write);
            fputs("|",fp_write);
            //printf("%s\n",file_str);
        }
        else if (strstr(file_str,start_drome))
        {
            p = strstr(file_str,start_drome);
            str_replace(p,strlen(start_drome),after);
            p = strstr(file_str,s_start_drome);
            str_replace(p,strlen(s_start_drome),after);
            fputs(a_trim(file_str),fp_write);
            fputs("|",fp_write);
            //printf("%s\n",file_str);
        }
        else if (strstr(file_str,arrive_drome))
        {
            p = strstr(file_str,arrive_drome);
            str_replace(p,strlen(arrive_drome),after);
            p = strstr(file_str,s_arrive_drome);
            str_replace(p,strlen(s_arrive_drome),after);
            fputs(a_trim(file_str),fp_write);
            fputs("|",fp_write);
            //printf("%s\n",file_str);
        }
        else if(strstr(file_str,start_time))
        {
            p = strstr(file_str,start_time);
            str_replace(p,strlen(start_time),after);
            p = strstr(file_str,s_start_time);
            str_replace(p,strlen(s_start_time),after);
            fputs(a_trim(file_str),fp_write);
            fputs("|",fp_write);
            //printf("%s\n",file_str);
        }
        else if(strstr(file_str,arrive_time))
        {
            p = strstr(file_str,arrive_time);
            str_replace(p,strlen(arrive_time),after);
            p = strstr(file_str,s_arrive_time);
            str_replace(p,strlen(s_arrive_time),after);
            fputs(a_trim(file_str),fp_write);
            fputs("|",fp_write);
            //printf("%s\n",file_str);
        }
        else if(strstr(file_str,air_mode))
        {
            p = strstr(file_str,air_mode);
            str_replace(p,strlen(air_mode),after);
            p = strstr(file_str,s_air_mode);
            str_replace(p,strlen(s_air_mode),after);
            fputs(a_trim(file_str),fp_write);
            fputs("|",fp_write);
            //printf("%s\n",file_str);
        }
        else if(strstr(file_str,air_stop))
        {
            p = strstr(file_str,air_stop);
            str_replace(p,strlen(air_stop),after);
            p = strstr(file_str,s_air_stop);
            str_replace(p,strlen(s_air_stop),after);
            fputs(a_trim(file_str),fp_write);
            fputs("|",fp_write);
            //printf("%s\n",file_str);
        }
        else if(strstr(file_str,cycle))
        {
            p = strstr(file_str,cycle);
            str_replace(p,strlen(cycle),after);
            p = strstr(file_str,s_cycle);
            str_replace(p,strlen(s_cycle),after);
            fputs(a_trim(file_str),fp_write);
            fputs("\n",fp_write);
            //printf("%s\n",file_str);
        }
        else
        {
            continue;
        }
        //printf("%s\n",q);
    }

    fclose(fp);
    fclose(fp_write);
    //printf("Writen file is:%s\n",tmp_file_name);
    save_airline_info(text_file,start_city,arrive_city,query_date);
}
// init_mariadb
init_mariadb函数
// An highlighted block
/*
 * 程序目的:获取数据库链接,同时定义回收数据库资源函数
 * 程序版本:C99
 * 程序编写:枫叶
 * 编写时间:2020年3月21日
 */
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <mysql/mysql.h>
#define FILENAME "db.txt"
#define BUFFLEN 256


MYSQL con;

//c中,会将换行符作为一个字符,所以需要去掉,避免获取信息不对
int clear_Enter(char *content)
{
    char *p = content;
    while('\n' != *p)
    {
        p++;
        if(*p == '\0')
        {
            return 0;
        }
    }
    *p = '\0';
    return 0;
}

//初始化mariadb连接的函数
MYSQL con_mariadb()
{
    //读取配置文件
    //定义一个二维数组,用于存储从文本文件获取的配置信息
    char conf[50][50] = {""};
    int i = 0;
    FILE *fp = NULL;
    char *file = FILENAME;
    char *line = (char *)malloc(BUFFLEN * sizeof(char));
    if((0 != access(file,R_OK|F_OK)) || (NULL==(fp=fopen(file,"r"))))
    {
        printf("open %s failed\n",file);
        exit(-1);
    }
    while( fgets(line, BUFFLEN, fp) != NULL )
    {
        //printf("the content of each line is:%s",line);
        //将读取的配置信息存入数组
        clear_Enter(line);
        strcpy(conf[i],line);
        //printf("conf[%d]=%s\n",i,conf[i]);
        i++;
    }
    printf("\n");
    if(fp!=NULL)
    {
        close(fp);
        printf("释放文件资源...\n");
    }
    //MYSQL con;
    mysql_init(&con);
    //int f;
    if(!mysql_real_connect(&con,conf[0],conf[1],conf[2],conf[3],atoi(conf[4]),conf[5],atoi(conf[6])))
    {
        //f = 0;//连接失败返回0

    }
    else
    {
        //f = 1;//连接成功返回1
        return con;
    }

    //return f;
}

void close_mariadb_con(MYSQL *con)
{
    mysql_close(con);
    printf("已关闭mariadb连接...\n");
}

void close_mariadb_result(MYSQL_ROW row)
{
    mysql_free_result(row);
    printf("已释放结果集...\n");
}
// store_data
store_data函数
// An highlighted block
/*
 * 程序目的:将数据插入数据库做好保存
 * 程序版本:C99
 * 程序编写:枫叶
 * 编写时间:2020年3月17日
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql/mysql.h>
#include "../head/airline.h"
#define LEN 1024
#define LENGTH 9
#define SPLIT "|"

MYSQL mysql;

int count = 0;//计算插入数据库的条数
void split_str(char **line, char *lines);
void insert_info_to_db(char* i_sql);

void save_airline_info(char* tmp_file_name,char* start_city,char* arrive_city,char* query_date)
{
    mysql = con_mariadb();//返回连接mariadb的状态
    //mysql_init(&mysql);
    //printf("flag:%d\n",f);
    int a = 0;//计算循环次数
    char lines[LEN];
    char* s_lines[LENGTH];
    FILE *fp = fopen(tmp_file_name,"r");
    printf("文件名:%s\n",tmp_file_name);
    printf("起飞城市:%s\n",start_city);
    printf("抵达城市:%s\n",arrive_city);
    printf("查询日期:%s\n",query_date);
    printf("------------------------------------------\n");
    char r_platform[] = "C99";
    if(fp == NULL)
    {
        printf("Can not open the file!\n");
        exit(1);
    }
    while(fgets(lines,LEN,fp)!=NULL)
    {
        char i_sql[1024] = "insert into airline(company,airlinecode,startdrome,arrivedrome,starttime,arrivetime,airmode,airlinestop,cycle,querydate,startcity,arrivecity,platform) values ('";
        a++;
        //去掉回车
        lines[strlen(lines)-1]='\0';
        split_str(s_lines,lines);
        while(1)
        {
            printf("序号:%d\n",a);
            printf("航空公司:%s\n",*(s_lines));

            printf("航空编号:%s\n",*(s_lines+1));
            printf("起飞机场:%s\n",*(s_lines+2));
            printf("抵达机场:%s\n",*(s_lines+3));
            printf("起飞时间:%s\n",*(s_lines+4));
            printf("抵达时间:%s\n",*(s_lines+5));
            printf("机型:%s\n",*(s_lines+6));
            printf("经停:%s\n",*(s_lines+7));
            printf("飞行周期:%s\n",*(s_lines+8));
            printf("-----------------------\n");
            //拼接sql
            strcat(strcat(strcat(strcat(strcat(strcat(strcat(strcat(strcat(strcat(strcat(strcat(strcat(strcat(strcat(strcat(strcat(strcat(strcat(strcat(strcat(strcat(strcat(strcat(strcat(strcat(i_sql,*(s_lines)),"','"),*(s_lines+1)),"','"),*(s_lines+2)),"','"),*(s_lines+3)),"','"),*(s_lines+4)),"','"),*(s_lines+5)),"','"),*(s_lines+6)),"','"),*(s_lines+7)),"','"),*(s_lines+8)),"','"),query_date),"','"),start_city),"','"),arrive_city),"','"),r_platform),"')");
            break;
        }
        if(&mysql)
        {
            //printf("insert sql:%s\n", i_sql);
            printf("连接数据库成功,准备插入数据...\n");
            insert_info_to_db(i_sql);
        }
    }
    printf("保存数据成功,共计保存%d条...\n",count);
    fclose(fp);
    close_mariadb_con(&mysql);
}
//按照分割符分割字符串
void split_str(char **line, char *lines)
{
    char *s = strtok(lines,SPLIT);
    while(s != NULL)
    {
        *line++ = s;
        s = strtok(NULL,SPLIT);
    }
}
//插入数据到mariadb
void insert_info_to_db(char i_sql[1024])
{
    printf("insert:%s\n",i_sql);
    int flag = mysql_real_query(&mysql, i_sql, (unsigned int)strlen(i_sql));
    //printf("insert flag:%d\n",flag);
    if(flag)
    {
        printf("保存数据失败...\n");
    }
    else
    {
        count++;

    }
}
// db.txt
db.txt数据库配置文件格式
// An highlighted block
IP地址
数据库用户名
数据库密码
连接的数据库名
连接的数据库端口号
NULL
0

你可能感兴趣的:(C)