用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://blog.ptsang.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"); } |
发表评论