调用libcurl库的curl_easy_perform函数后,程序崩溃
#include "sina.h"
#include <string>
#define HTTP_GET "GET"
#define HTTP_PUT "PUT"
#define HTTP_HEAD "HEAD"
#define HTTP_POST "POST"
#define HTTP_DELETE "DELETE"
#define HTTP_RET_OK "HTTP/1.1 200 OK\r\n"
#define SINA_HOST "hq.sinajs.cn"
#define SINA_PORT 80
#define STEPTIME 100
std::string truncateToLastNewline(const std::string& str) {
size_t pos = str.find_last_of('\n');
if (pos != std::string::npos) {
return str.substr(0, pos + 1); // 包含最后的'\n'字符
}
return str; // 如果没有'\n',原样返回字符串
}
size_t callback_get_head(void* ptr, size_t size, size_t nmemb, void* userp)
{
// strcat((char*)userp, (char*)ptr);
// return size * nmemb; //必须返回这个大小, 否则只回调一次
char* str = (char*)userp;
if (str == nullptr) {
return 0; // 如果 userp 是 NULL,则不进行任何操作
}
size_t len = strlen(str);
size_t newlen = len + size * nmemb;
//if (len==0)
//{
// return 0;
//}
// 确保有足够的空间来存储新的数据
if (newlen > len) {
str = (char*)realloc(str, newlen + 1); // +1 for null terminator
if (str == nullptr) {
return 0; // realloc 失败
}
userp = str; // 更新 userp 到新分配的内存
}
memcpy(str + len, ptr, size * nmemb);
str[newlen] = '\0'; // 添加 null 终止符
return size * nmemb;
}
static char connect_cloud(char* pc_ret, const char* host_addr, const int portno,
const char* pc_method, struct curl_slist* http_headers)
{
CURL* curl;
CURLcode res = CURLE_GOT_NOTHING;
assert((pc_ret != NULL) && (host_addr != NULL) && (pc_method != NULL));
//curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if (!curl) {
fprintf(stderr, "--- curl init Error!\n");
return 0;
}
curl_easy_setopt(curl, CURLOPT_URL, host_addr);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3); //设置超时, 单位为秒.
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); //屏蔽其它信号, makes libcurl NOT ask the system to ignore SIGPIPE signals
curl_easy_setopt(curl, CURLOPT_HEADER, 1L); //下载数据包括HTTP头部, The default value for this parameter is 0.
#if (CURL_DBG == 1)
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); //调试用: 显示交互明细,
#endif
/* struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(headers, "Referer: http://finance.sina.com.cn");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_slist_free_all(headers);
*/
// header_list = curl_slist_append(header_list, "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko");
// header_list = curl_slist_append(header_list, "Content-Type:application/x-www-form-urlencoded; charset=UTF-8");
// header_list = curl_slist_append(header_list, "Referer:http://finance.sina.com.cn");
// curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
#if 1
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, pc_method);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback_get_head); //下载数据的回调函数
curl_easy_setopt(curl, CURLOPT_WRITEDATA, pc_ret); //下载数据的指针
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, http_headers); //多行的HTTP头部
//curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3); //连接超时限制
//curl_easy_setopt(curl, CURLOPT_TIMEOUT, 80); //整个CURL操作的超时限制
// 强制使用 IPv4
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
#endif
res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
curl_easy_cleanup(curl);
return 0;
}
curl_easy_cleanup(curl);
return 1;
}
int sina_get_stock(char* pc_ret, const char* pc_stockid)
{
char pc_url[200], ret;
char* pc_stock = new char[40];
memcpy(pc_stock, pc_stockid, 40);
//组织请求头部, 自动末尾添加'\r\n'
struct curl_slist* http_headers = NULL;
http_headers = curl_slist_append(http_headers, "content-type: application/x-www-form-urlencoded;charset=UTF-8");
http_headers = curl_slist_append(http_headers, "Referer: http://finance.sina.com.cn");
http_headers = curl_slist_append(http_headers, "charsets: utf-8");
//发送请求, 再判断返回值
//url = hq.sinajs.cn/list=sz150013
int len = strlen(pc_stock); // 计算字符串长度
// 小写转换为大写
//for (int i = 0; i < len; i++) {
// if (pc_stock[i] >= 'a' && pc_stock[i] <= 'z') {
// pc_stock[i] -= 32; // 将小写字母转换为大写
// }
//}
// 大写转换为小写
for (int i = 0; i < len; i++) {
if (pc_stock[i] >= 'A' && pc_stock[i] <= 'Z') {
pc_stock[i] += 32; // 将大写字母转换为小写
}
}
// 输出转换后的字符串
puts(pc_stock);
//char pc_url[BUFFER_SIZE];
// 正确的 snprintf 调用
sprintf(pc_url, "%s/list=%s", SINA_HOST, pc_stock);
//pc_url = 0x000000a6028feeb0 "hq.sinajs.cn/list=sh601069"
//snprintf(pc_url, BUFFER_SIZE, "%s/list=%s", SINA_HOST, pc_stock);
//snprintf(pc_url, 120, "%s/list=%s", SINA_HOST, pc_stock);
ret = connect_cloud(pc_ret, pc_url, SINA_PORT, HTTP_GET, http_headers);
//DBG("cloud ret = %s\n", pc_ret);
//释放 http_headers资源
curl_slist_free_all(http_headers);
delete[]pc_stock;
return(ret);
}
#if 0
/*字符串不同含义的数据用逗号隔开了,按照程序员的思路,顺序号从0开始。
0:”大秦铁路”,股票名字;
1:”27.55″,今日开盘价;
2:”27.25″,昨日收盘价;
3:”26.91″,当前价格;
4:”27.55″,今日最高价;
5:”26.20″,今日最低价;
6:”26.91″,竞买价,即“买一”报价;
7:”26.92″,竞卖价,即“卖一”报价;
8:”22114263″,成交的股票数,由于股票交易以一百股为基本单位,所以在使用时,通常把该值除以一百;
9:”589824680″,成交金额,单位为“元”,为了一目了然,通常以“万元”为成交金额的单位,所以通常把该值除以一万;
10:”4695″,“买一”申请4695股,即47手;
11:”26.91″,“买一”报价;
12:”57590″,“买二”
13:”26.90″,“买二”
14:”14700″,“买三”
15:”26.89″,“买三”
16:”14300″,“买四”
17:”26.88″,“买四”
18:”15100″,“买五”
19:”26.87″,“买五”
20:”3100″,“卖一”申报3100股,即31手;
21:”26.92″,“卖一”报价
(22, 23), (24, 25), (26,27), (28, 29)分别为“卖二”至“卖四的情况”
30:”2008-01-11″,日期;
31:”15:05:32″,时间;*/
#endif
void stock_parse(stock_info_t* stock, const char* pc_data)
{
char* pc_str, * pc_str1;
int i;
assert((stock != NULL) && (pc_data != NULL));
// 查找 HTTP_RET_OK
pc_str = strstr((char*)pc_data, HTTP_RET_OK);
if (pc_str) {
pc_str += strlen(HTTP_RET_OK);
// 查找 \r\n\r\n
pc_str = strstr(pc_str, "\r\n\r\n");
if (pc_str) {
pc_str += 4;
// 查找第一个逗号
pc_str = strchr(pc_str, ',');
if (pc_str == NULL) {
return;
}
pc_str++;
for (i = 0; i < 5; i++) {
pc_str1 = strchr(pc_str, ',');
if (pc_str1) {
*pc_str1 = '\0';
switch (i) {
case 0: stock->price_open = atof(pc_str); break; // 今开
case 1: stock->price_refclose = atof(pc_str); break; // 昨收
case 2: stock->price_close = atof(pc_str); break; // 当前
case 3: stock->price_high = atof(pc_str); break; // 今高
case 4: stock->price_low = atof(pc_str); break; // 今低
}
pc_str = pc_str1 + 1; // 指向下个有效数据
}
else {
break; // 无法找到更多的逗号,退出循环
}
}
}
}
}
上面这个代码在LINUX上跑好几年了,没问题,可是在WINDOWS10上就崩溃,具体是在 res = curl_easy_perform(curl); 这一行进去后崩溃的,无法运行到下一句 if(res != CURLE_OK) , 各种手段都试过了,不知道怎么解决,和找到出错的原因