为了完成作业,就偷个懒糊了个获取手机归属地的程序,。我原本写的是MFC版本的,但是由于MFC的代码不是很通用,加上我没有学MFC的时候看别人MFC代码只能干瞪眼,看不懂,所以便改成控制台版本的了。但这API还害得我找了老半天,不是功能少就是根本用不了(例如youdao)文中所用的API地址是 http://api.showji.com/Locating/www.showji.co.m.aspx,有两个参数:
m | 手机号,由11位数字组成 |
output | 可以为xml或json |
注:浏览器显示可能有些问题,毕竟<Mobile>等标签浏览器是无法识别的,可以在“查看源文件”中查看
我使用的是xml格式。json解析可以用jsoncpp,就是不知道怎么在VC6下使用,若您了解,还请你回复讲解。
思路很简单,URLDownLoadToFile()下载文件,再写个函数解析,好,开始!
// 头文件 #include <stdio.h> #include <windows.h> #include <urlmon.h> #pragma comment( lib, "urlmon.lib" )
// 为了复制粘贴方便,写了2个宏 #define GETEND( str ) (SreachStr( MobileInfo, str ) + strlen( str )) #define GETSTART( str ) (SreachStr( MobileInfo, str ) - 1)
// 函数Utf8_to_ascii,API大多都是UTF8格式的,要用此函数转换成ascii char *Utf8_to_ascii( char utf8[] ) { int len = MultiByteToWideChar( CP_UTF8, 0, utf8, -1, NULL, 0); wchar_t *wstr = new wchar_t[len+1]; memset( wstr, 0, len + 1); MultiByteToWideChar( CP_UTF8, 0, utf8, -1, wstr, len); len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL); char *str = new char[len+1]; memset(str, 0, len+1); WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL); if( wstr ) { delete[] wstr; } return str; }
// 函数SreachStr,寻找API中间<...>...</...>的数据 int SreachStr( const char str1[], const char str2[] ) { int i = 0; int j = 0; int len1 = strlen( str1 ); int len2 = strlen( str2 ); for( i = 0; i < len1; i++ ) { bool Findit = true; for( j = i; j < len2 + i; j++ ) { if( str2[j-i] != str1[j] ) { Findit = false; } } if( Findit ) { return i; } } return -1; }
主函数似乎太长了点……
int main( int argc, char *argv[] ) { char Mobilenum[11]; HRESULT hDownToFile; // 文件下载句柄 HANDLE hMobileFile; // 手机信息句柄 char chUrl[100]; unsigned long nReadSize = 0; memset( Mobilenum, 0, 11 ); memset( chUrl, 0, 100 ); scanf( "%s", Mobilenum ); strcpy( chUrl, "http://api.showji.com/Locating/www.showji.co.m.aspx?m="); strcat( chUrl, Mobilenum ); strcat( chUrl, "&output=xml" ); hDownToFile = URLDownloadToFile( 0, chUrl, TEXT("Temp File.tmp"), NULL, NULL ); if( hDownToFile != S_OK ) { printf( "下载失败! " ); return 0; } hMobileFile = CreateFile( "Temp File.tmp", // 文件名 GENERIC_READ, // 读文件操作 NULL, NULL, OPEN_EXISTING, // 打开文件 FILE_FLAG_DELETE_ON_CLOSE, // 作为临时文件 NULL); if ( hMobileFile == INVALID_HANDLE_VALUE ) { printf( "打开文件失败! " ); return 0; } char ReadData_UTF8[400]; char MobileInfo[400]; memset( ReadData_UTF8, 0, 400); if ( ReadFile( hMobileFile, ReadData_UTF8, 400, &nReadSize, NULL ) == FALSE ) { printf( "读取文件失败! %d", GetLastError() ); return 0; } strcpy( MobileInfo, Utf8_to_ascii(ReadData_UTF8) ); CloseHandle( hMobileFile ); /************************** 读取工作结束 *************************/ /************************** 开始解析数据 *************************/ char temp[30]; int i = 0; int start = GETEND( "<QueryResult>" ); int end = GETSTART( "</QueryResult>" ); memset( temp, 0, 30); for( i = start; i <= end; i ++ ) { temp[i - start] = MobileInfo[i]; } if( !strcmp( temp, "False") ) { printf( "号码不存在或暂无数据! " ); return 0; } start = GETEND( "<City>" ); end = GETSTART( "</City>" ); memset( temp, 0, 30); for( i = start; i <= end; i ++ ) { temp[i - start] = MobileInfo[i]; } printf( "所 在 地: %s ", temp ); start = GETEND( "<AreaCode>" ); end = GETSTART( "</AreaCode>" ); memset( temp, 0, 30); for( i = start; i <= end; i ++ ) { temp[i - start] = MobileInfo[i]; } printf( "区 号: %s ", temp ); start = GETEND( "<PostCode>" ); end = GETSTART( "</PostCode>" ); memset( temp, 0, 30); for( i = start; i <= end; i ++ ) { temp[i - start] = MobileInfo[i]; } printf( "邮政编码: %s ", temp ); start = GETEND( "<Corp>" ); end = GETSTART( "</Corp>" ); memset( temp, 0, 30); for( i = start; i <= end; i ++ ) { temp[i - start] = MobileInfo[i]; } printf( "运 营 商: %s ", temp ); start = GETEND( "<Province>" ); end = GETSTART( "</Province>" ); memset( temp, 0, 30); for( i = start; i <= end; i ++ ) { temp[i - start] = MobileInfo[i]; } printf( "省 份: %s ", temp ); return 0; }
总算完成了。运行界面如图:
源码下载地址: