继续CETQuery——C语言版

用C来做这个题目还真是截然不同的感觉,没有HTTPConnection,没有urllib,所有报文都得自己构建自己解析……更麻烦的是中文问题,不得不调用到系统库来进行解码……

貌似这次最满意的一行代码是:

char type = (id[9] – 1) ? ‘6’ : ‘4’;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <iconv.h>   
 
void PANIC(char *msg);
#define PANIC(msg)  {perror(msg); abort();}
int tcp_connect(const char *host, const char *serv);
int code_convert(char *from_charset, char *to_charset,
            char *inbuf, int inlen, char *outbuf, int outlen);
void display_list(char *result, char type, char *id);
 
int 
main(int argc, char *argv[])
{
    int sockfd, bytes_read;
    char buffer[4096];
    char result[100];
    char *id;
 
    if(argc != 2 || strlen(argv[1]) != 15) {
        printf("Error: 参数错误,请输入15位准考证号,自动识别考试类型。"
            "nExample:nnCETQuery 123456789012345nn"
            "CETQuery-C version 0.3  2009.3.2nn    An Exercise Program by PT, GZ Universityn    "
            "Author Blog: http://apt-blog.net , Welcome to Drop by.nn");
        exit(1);
    }
 
    id = argv[1];
    char type = (id[9] - 1) ? '6' : '4';
 
    /* 建立连接socket   */
    sockfd = tcp_connect("cet.99sushe.com", "http");
 
    /* 准备HTTP头数据 */
    sprintf(buffer, "GET /cetscore_99sushe0902.html?t=%c&id=%s HTTP/1.1rnReferer: http://cet.99sushe.com/rnHost: cet.99sushe.comrnrn", type, id);
 
    /* 发送数据 */
    send(sockfd, buffer, strlen(buffer), 0);
 
    /* 接收缓存 */
    bzero(buffer, sizeof(buffer));
 
    /* 接收 */
    bytes_read = recv(sockfd, buffer, sizeof(buffer), 0);
 
    /* 关闭套接字 */
    close(sockfd);
 
    /* 错误处理 */
    if ( bytes_read <= 0 ){
        PANIC("MAIN");
        exit(1);
    }
 
    /* 信息头过滤 */
    char *metadata = strstr(buffer,"rnrn");
    metadata += 4;
 
    /* 转码缓存 */
    bzero(result, sizeof(result));
    code_convert("gb2312", "utf-8", metadata, strlen(metadata), result, 100);
 
    /* 输出结果 */
    display_list(result, type, id);
 
    return 0;
}/* ----------  end of function main  ---------- */
 
int
tcp_connect(const char *host, const char *serv)
{
    int     sockfd, n;
    struct addrinfo hints, *res, *ressave;
 
    bzero(&hints, sizeof(struct addrinfo));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
 
    if( (n = getaddrinfo(host, serv, &hints, &res)) != 0)
        PANIC("tcp_connect");
    ressave = res;
 
    do {
        sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
 
        if (sockfd < 0)
          continue;
 
        if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)
          break;
        close(sockfd);
    }while( (res = res->ai_next) != NULL);
    freeaddrinfo(ressave);
    return (sockfd);
}
 
 
int code_convert(char *from_charset, char *to_charset,
            char *inbuf, int inlen, char *outbuf, int outlen)
{
    iconv_t cd;
    int rc;
    char **pin = &inbuf;
    char **pout = &outbuf;
 
    cd = iconv_open(to_charset,from_charset);
 
    if (cd==0) 
      return -1;
    memset(outbuf,0,outlen);
 
    if (iconv(cd, pin, &inlen, pout, &outlen)==-1) 
      return -1;
    iconv_close(cd);
    return 0;
}
 
void display_list(char *result, char type, char *id)
{
    int  count = 0;
    char* token;
    char record[10][20];
    char colum[][10] = {"听力", "阅读", "综合", "写作", "总分", 
        "学校", "姓名", "Prev 1", "Next 1", "Next 2"};
 
    /* 逗号分割 */
    token = strtok(result, ",");
    while( token != NULL )
    {
         sprintf(record[count++], "%s", token);
         token = strtok( NULL, ",");
    }
 
    /* 错误处理 */
    if(count > 10)
      PANIC("TOKEN Error!!");
 
    /* 输出 */
    printf("n***** CET %c 成绩清单 *****n"
            "-准考证号: %sn", type, id);
    for(count = 0; count < 10; count++) {
        printf("-%s: %sn", colum[count],record[count]);
    }
    printf("**************************nn");
}
文章分类 C/C++, Unix/Linux 标签: , ,

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*