sizeof(city_array) = 8, sizeof(char *) = 8


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/**
 * sizeof(city_array) = 8, sizeof(char *) = 8
 * count = sizeof(city_array) / sizeof(char *) = 1
 */
void print_city_array(int num, char **city_array){
	printf("sizeof(city_array) = %d, sizeof(char *) = %d\n", sizeof(city_array), sizeof(char *));
	printf("count = sizeof(city_array) / sizeof(char *) = %d\n", sizeof(city_array)/sizeof(char *));

	int i;
	for(i = 0; i < num; i++){
		puts(city_array[i]);
	}
}
/**
 * ==:sizeof(array) = 8, sizeof(int *) = 8, sizeof(array)/sizeof(int) = 2
 */
int get_total(int sum, int *array){
	printf("==:sizeof(array) = %d, sizeof(int *) = %d, sizeof(array)/sizeof(int) = %d\n",
			sizeof(array), sizeof(int *), sizeof(array)/sizeof(int) );

	int i, total = 0;
	for(i = 0; i < sum; i++)
		total += array[i];
	return total;
}

int main(int argc, char *argv[]) {
	char *city_array[] = {
			"beijing",
			"shanghai",
			"wuhan",
			"xian"
	};

	puts("==========main starting========");
	printf("sizeof(city_array) = %d, sizeof(char *) = %d\n", sizeof(city_array), sizeof(char *));
	printf("count = sizeof(city_array) / sizeof(char *) = %d\n", sizeof(city_array)/sizeof(char *));

	int i;
	for(i = 0; i < sizeof(city_array)/sizeof(char *); i++){
		puts(city_array[i]);
	}
	puts("==========main ending========");
	print_city_array(4, city_array);

	int array[] = {1, 9, 2, 8, 3, 7, 4, 6, 5};
	int total = get_total(9, array);
	printf("total = %d\n", total);
	return 0;
}



分析/* ubus变量 */ static struct ubus_context *ubus_ctx = NULL; static char *ubus_patch; /* uci变量 */ static struct uci_context *uci_ctx = NULL; static struct uci_package *uci_weather = NULL; /* uloop */ struct uloop_timeout timer; /* ubus数据接口结构 */ enum { TEMPERATURE_UNIT, LOCATION_KEY, CITY_NAME, WEATHER_SETTINGS_MAX }; /* ubus参数解析policy */ static const struct blobmsg_policy ubus_policy[] = { [TEMPERATURE_UNIT] = {.name = "temperature_unit", .type = BLOBMSG_TYPE_INT32}, [LOCATION_KEY] = {.name = "location_key", .type = BLOBMSG_TYPE_INT32}, [CITY_NAME] = {.name = "city", .type = BLOBMSG_TYPE_STRING}, }; static struct ubus_event_handler weather_settings_ubus_notify = {.cb = ubus_collect_now}; /* 更新时间间隔 */ #define DEFAULT_INTERVAL 21600 //6h #define MID_INTERVAL 300 //5min #define FAST_INTERVAL 10 //10s static int renew_interval = DEFAULT_INTERVAL; #define MAX_URL_LEN 256 #define POST_TRANSFER_TIMEOUT 5 #define POST_CONNECT_TIMEOUT 5 #define MAX_TOKEN_LEN 128 /* 相关文件地址 */ #define FILE_CLOUD_TOKEN_WEATHER "/tmp/cloud/cloud_token_weather" #define REALTIME_URL_POSTFIX "/v1/weather/realtime" #define FORECASTS_URL_POSTFIX "/v1/weather/forecasts" #define CA_CRT_PATH "/etc/certificate/2048_newroot.cer" /* * brief 保存post执行结果status code. */ typedef struct _st_http_resinfo { long status_code; }st_http_resinfo; /* * brief 保存当日天气数据. */ struct realtime_weather_info_struct{ int temperature; int temperatureMax; int temperatureMin; char weatherType[10]; }; static struct realtime_weather_info_struct realtime_weather_info; /* * brief 保存未来三日天气数据. */ struct forecast_weather_info_struct{ int temperatureMax; int temperatureMin; char dayWeatherType[10]; char nightWeatherType[10]; }; static struct forecast_weather_info_struct forecast_weather_info[3]; static int weather_errorcode = 0; /* 云端回传错误代码 */ static char weather_message[20]; /* 云端回传错误信息 */ /**************************************************************************************************/ /* LOCAL_FUNCTIONS */ /**************************************************************************************************/ /* * fn char* Int2String(int num,char *str) * details int转string * * param[in] num:待转换int str:指向转换得到字符串的指针 * param[out] * * return str:指向转换得到字符串的指针 * * note */ char* Int2String(int num,char *str)//10进制 { int i = 0;//指示填充str if(num<0)//如果num为负数,将num变正 { num = -num; str[i++] = '-'; } //转换 do { str[i++] = num%10+48;//取num最低位 字符0~9的ASCII码是48~57;简单来说数字0+48=48,ASCII码对应字符'0' num /= 10;//去掉最低位 }while(num);//num不为0继续循环 str[i] = '\0'; //确定开始调整的位置 int j = 0; if(str[0]=='-')//如果有负号,负号不用调整 { j = 1;//从第二位开始调整 ++i;//由于有负号,所以交换的对称轴也要后移1位 } //对称交换 for(;j<i/2;j++) { //对称交换两端的值 其实就是省下中间变量交换a+b的值:a=a+b;b=a-b;a=a-b; str[j] = str[j] + str[i-1-j]; str[i-1-j] = str[j] - str[i-1-j]; str[j] = str[j] - str[i-1-j]; } return str;//返回转换后的值 } /********************************************ubus相关函数*******************************************/ /* * fn static void weather_ubus_update_event_generate(int flag); * details 通过ubus send将更新得到的天气数据发送给其他相关模块 * * param[in] * param[out] * * return * * note */ static void weather_ubus_update_event_generate(int flag) { static struct blob_buf g_ubus_buf; void *table_len = NULL; time_t timep; struct tm date; blob_buf_init(&g_ubus_buf, 0); time(&timep); /* 获取当前unix时间 */ if(0 == flag) /* 0 == flag,发送当日实时天气数据 */ { date = *(localtime(&timep)); table_len = blobmsg_open_table(&g_ubus_buf, "realtime"); blobmsg_add_u32(&g_ubus_buf , "month" , date.tm_mon + 1); blobmsg_add_u32(&g_ubus_buf , "day" , date.tm_mday); blobmsg_add_u32(&g_ubus_buf , "temperature" , realtime_weather_info.temperature); blobmsg_add_u32(&g_ubus_buf , "temperature_min" , realtime_weather_info.temperatureMin); blobmsg_add_u32(&g_ubus_buf , "temperature_max" , realtime_weather_info.temperatureMax); blobmsg_add_string(&g_ubus_buf , "weather_type" , realtime_weather_info.weatherType); blobmsg_close_table(&g_ubus_buf, table_len); INFO("[weather_server]: Ubus send realtime weather, renew time:%ld", timep); } else /* 1 == flag,发送未来三天天气数据 */ { timep += 86400; /* 调整到后一天同一时刻 */ date = *(localtime(&timep)); table_len = blobmsg_open_table(&g_ubus_buf, "tomorrow"); blobmsg_add_u32(&g_ubus_buf , "month" , date.tm_mon + 1); blobmsg_add_u32(&g_ubus_buf , "day" , date.tm_mday); blobmsg_add_u32(&g_ubus_buf , "temperature_min" , forecast_weather_info[0].temperatureMin); blobmsg_add_u32(&g_ubus_buf , "temperature_max" , forecast_weather_info[0].temperatureMax); blobmsg_add_string(&g_ubus_buf , "day_weather_type" , forecast_weather_info[0].dayWeatherType); blobmsg_add_string(&g_ubus_buf , "night_weather_type" , forecast_weather_info[0].nightWeatherType); blobmsg_close_table(&g_ubus_buf, table_len); timep += 86400; /* 调整到后一天同一时刻 */ date = *(localtime(&timep)); table_len = blobmsg_open_table(&g_ubus_buf, "2_days_later"); blobmsg_add_u32(&g_ubus_buf , "month" , date.tm_mon + 1); blobmsg_add_u32(&g_ubus_buf , "day" , date.tm_mday); blobmsg_add_u32(&g_ubus_buf , "temperature_min" , forecast_weather_info[1].temperatureMin); blobmsg_add_u32(&g_ubus_buf , "temperature_max" , forecast_weather_info[1].temperatureMax); blobmsg_add_string(&g_ubus_buf , "day_weather_type" , forecast_weather_info[1].dayWeatherType); blobmsg_add_string(&g_ubus_buf , "night_weather_type" , forecast_weather_info[1].nightWeatherType); blobmsg_close_table(&g_ubus_buf, table_len); timep += 86400; /* 调整到后一天同一时刻 */ date = *(localtime(&timep)); table_len = blobmsg_open_table(&g_ubus_buf, "3_days_later"); blobmsg_add_u32(&g_ubus_buf , "month" , date.tm_mon + 1); blobmsg_add_u32(&g_ubus_buf , "day" , date.tm_mday); blobmsg_add_u32(&g_ubus_buf , "temperature_min" , forecast_weather_info[2].temperatureMin); blobmsg_add_u32(&g_ubus_buf , "temperature_max" , forecast_weather_info[2].temperatureMax); blobmsg_add_string(&g_ubus_buf , "day_weather_type" , forecast_weather_info[2].dayWeatherType); blobmsg_add_string(&g_ubus_buf , "night_weather_type" , forecast_weather_info[2].nightWeatherType); blobmsg_close_table(&g_ubus_buf, table_len); INFO("[weather_server]: Ubus send forecast weather, renew time:%ld", timep - 86400 * 3); } /* ubus send event */ ubus_send_event(ubus_ctx, "weather_info_update", g_ubus_buf.head); } /* * fn static void ubus_collect_now(struct ubus_context *ubus_ctx, * struct ubus_event_handler *ev, * const char *type, struct blob_attr *msg); * details ubus对象方法回调函数,响应ubus send weather_settings_update,更新地理位置参数并立即更新天气信息 * * param[in] * param[out] * * return * * note */ static void ubus_collect_now(struct ubus_context *ubus_ctx, struct ubus_event_handler *ev, const char *type, struct blob_attr *msg) { int status = 0; int temperature_unit = -1; uint32_t location_key = 0; struct blob_attr *tb[WEATHER_SETTINGS_MAX] = {NULL}; char buf[128] = {0}; status = blobmsg_parse(ubus_policy, WEATHER_SETTINGS_MAX, tb, blob_data(msg), blob_len(msg)); if (status < 0) { return; } if (tb[TEMPERATURE_UNIT] && blob_data(tb[TEMPERATURE_UNIT])) { temperature_unit = blobmsg_get_u32(tb[TEMPERATURE_UNIT]); } else { ERR("invalid temperature_unit"); } if (tb[LOCATION_KEY] && blob_data(tb[LOCATION_KEY])) { location_key = blobmsg_get_u32(tb[LOCATION_KEY]); } else { ERR("invalid location_key"); } if (tb[CITY_NAME] && blob_data(tb[CITY_NAME])) { snprintf(buf, sizeof(buf), "%s", blobmsg_get_string(tb[CITY_NAME])); } else { ERR("invalid city_name"); } INFO("[weather_server] Ubus rec: temperature_unit=%d, location_key=%d, city_name=%s",temperature_unit, location_key, buf); /* 更新天气信息 */ weather_timer_cb(&timer); } /* * fn static void ubus_reconn_timer(struct uloop_timeout *timeout) * details ubus重连 * * param[in] * param[out] * * return * * note */ static void ubus_reconn_timer(struct uloop_timeout *timeout) { static struct uloop_timeout retry = { .cb = ubus_reconn_timer, }; DEBUG("S:ubus_connection_lost"); if (ubus_reconnect(ubus_ctx, ubus_patch) != 0) { /* 设置每过两秒尝试重连ubusd */ uloop_timeout_set(&retry, 2000); return; } ubus_add_uloop(ubus_ctx); } /* * fn static int weather_ubus_init(char *path) * details ubus初始化 * * param[in] * param[out] * * return * * note */ static int weather_ubus_init(char *path) { ubus_patch = path; /* 连接ubusd */ ubus_ctx = ubus_connect(path); if (!ubus_ctx) { ERR("S:Failed to connect ubusd"); return -1; } /* 设置断线重连回调函数为ubus_reconn_timer */ ubus_ctx->connection_lost = (void (*)(struct ubus_context *))ubus_reconn_timer; DEBUG("S:succeed to connect ubusd"); if (ubus_register_event_handler(ubus_ctx, &weather_settings_ubus_notify, "weather_settings_update") != 0) { ERR("S:Failed to add object to ubusd"); return -1; } /* 向uloop注册 */ ubus_add_uloop(ubus_ctx); DEBUG("S:succeed to add object to ubusd"); return 0; } /* * fn static int weather_ubus_deinit(void) * details 释放ubus变量 * * param[in] * param[out] * * return * * note */ static int weather_ubus_deinit(void) { ubus_unregister_event_handler(ubus_ctx, &weather_settings_ubus_notify); if(ubus_ctx) { ubus_free(ubus_ctx); } return 0; } /**********************************************天气信息请求*****************************************/ /* * fn static size_t OnWriteData_Post(void* buffer, size_t size, size_t nmemb, void* lpVoid) * details 将从云端收到的数据写入复制到指定字符串中 * * param[in] * param[out] * * return * * note */ static size_t OnWriteData_Post(void* buffer, size_t size, size_t nmemb, void* lpVoid) { unsigned int len = (unsigned int)size * (unsigned int)nmemb; char *str = malloc(len + 1); if (NULL == str || NULL == buffer) { return -1; } char* pData = buffer; memset(str, 0, len + 1); memcpy(str, pData, len); DEBUG("response: %s", str); char **response = lpVoid; *response = str; return len; } /* * fn static size_t cloud_https_post(const char *pUrl, const char *requestHeader, * const char *request, char **response, st_http_resinfo *pHttpResInfo) * details 发送post请求,从云端获取天气数据 * * param[in] * param[out] * * return * * note */ static size_t cloud_https_post(const char *pUrl, const char *requestHeader, const char *request, char **response, st_http_resinfo *pHttpResInfo) { CURLcode res; CURL* curl = NULL; struct curl_slist *headers = NULL; if (NULL == pUrl || NULL == request || NULL == response || NULL == pHttpResInfo) { return CURLE_FAILED_INIT; } DEBUG("pUrl:%s requestHeader:%s request:%s", pUrl, requestHeader, request); res = curl_global_init(CURL_GLOBAL_ALL); if (CURLE_OK != res) { ERR("curl global init fail and ret %d", res); return res; } curl = curl_easy_init(); if (NULL == curl) { res = CURLE_FAILED_INIT; ERR("curl init fail"); goto exit; } // headers = curl_slist_append(headers, "Content-Type: application/json;charset=UTF-8"); headers = curl_slist_append(headers, "Content-Type: application/json"); if (NULL == headers) { ERR("curl get header list fail"); goto exit; } if ((NULL != requestHeader) && (0 < strlen(requestHeader))) { DEBUG("requestHeader is %s", requestHeader); headers = curl_slist_append(headers, requestHeader); if (NULL == headers) { ERR("curl append requestHeader fail"); goto exit; } } //set url // DEBUG("request_url:%s",pUrl); res = curl_easy_setopt(curl, CURLOPT_URL, pUrl); if (CURLE_OK != res) { ERR("curl set option CURLOPT_URL ret %d", res); goto exit; } //set header //DEBUG("request_header:%s",headers); res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); if (CURLE_OK != res) { ERR("curl set option CURLOPT_HTTPHEADER ret %d", res); goto exit; } //set post method res = curl_easy_setopt(curl, CURLOPT_POST, 1); if (CURLE_OK != res) { ERR("curl set option CURLOPT_POST ret %d", res); goto exit; } // DEBUG("request_data:%s",request); res = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request); if (CURLE_OK != res) { ERR("curl set option CURLOPT_POSTFIELDS ret %d", res); goto exit; } //set read/write params res = curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); if (CURLE_OK != res) { ERR("curl set option CURLOPT_READFUNCTION ret %d", res); goto exit; } res = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData_Post); if (CURLE_OK != res) { ERR("curl set option CURLOPT_WRITEFUNCTION ret %d", res); goto exit; } res = curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)response); if (CURLE_OK != res) { ERR("curl set option CURLOPT_WRITEDATA ret %d", res); goto exit; } res = curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); if (CURLE_OK != res) { ERR("curl set option CURLOPT_NOSIGNAL ret %d", res); goto exit; } //set certificate info res = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); if (CURLE_OK != res) { ERR("curl set option CURLOPT_SSL_VERIFYPEER ret %d", res); goto exit; } res = curl_easy_setopt(curl, CURLOPT_CAINFO, CA_CRT_PATH); if (CURLE_OK != res) { ERR("curl set option CURLOPT_CAINFO ret %d", res); goto exit; } //set CURLOPT_CONNECTTIMEOUT res = curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, POST_TRANSFER_TIMEOUT); if (CURLE_OK != res) { ERR("curl set option CURLOPT_CONNECTTIMEOUT ret %d", res); goto exit; } //set CURLOPT_TIMEOUT res = curl_easy_setopt(curl, CURLOPT_TIMEOUT, POST_CONNECT_TIMEOUT); if (CURLE_OK != res) { ERR("curl set option CURLOPT_TIMEOUT ret %d", res); goto exit; } //CURLOPT needs to be set_ FOLLOWLOCATION is 1, otherwise, the data after redirecting will not be returned res = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); if (CURLE_OK != res) { ERR("curl set option CURLOPT_FOLLOWLOCATION ret %d", res); goto exit; } res = curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); if (CURLE_OK != res) { ERR("curl set option CURL_SSLVERSION_TLSv1_2 ret %d", res); goto exit; } res = curl_easy_perform(curl); curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &(pHttpResInfo->status_code)); DEBUG("cloud_https_post done. ret %d, http status code %d", res, pHttpResInfo->status_code); exit: if (headers) { curl_slist_free_all(headers); } if (curl) { curl_easy_cleanup(curl); } curl_global_cleanup(); return res; } /* * fn int get_token_url(char *token, char *url) * details 获取device token和云端天气预报请求url * * param[in] * param[out] * * return * * note */ int get_token_url(char *token, char *url) { int ret = -1; int retry_count = 3; FILE *fp = NULL; while (retry_count > 0) { if((fp = fopen(FILE_CLOUD_TOKEN_WEATHER, "r"))) { fscanf(fp, "%s", token); fscanf(fp, "%s", url); fclose(fp); ret = 0; break; } else { system("cloud_getDevToken weather"); } retry_count--; } return ret; } /* * fn static void set_weather_cloud_request_data(char *device_token, char *request_data) * details 读取uci配置中的location_key,与输入参数device_token共同构造post请求参数 * * param[in] char *device_token 从云端获取的device token * char *request_data 存储post请求参数字符串 * param[out] * * return * * note */ static void set_weather_cloud_request_data(char *device_token, char *request_data) { //int ret = -1; json_object* request_data_json = NULL; const char* request_data_out = NULL; //FILE *fp = NULL; int locationkey = 0; if ((request_data_json = json_object_new_object()) == NULL) { goto out; } locationkey = uci_get_locationkey(); if ( -1 == locationkey) { ERR("uci_get_locationkey failed"); goto out; } json_object_object_add(request_data_json, "locationKey", json_object_new_int(locationkey)); json_object_object_add(request_data_json, "deviceToken", json_object_new_string(device_token)); request_data_out = json_object_to_json_string(request_data_json); memcpy(request_data, request_data_out, strlen(request_data_out)); json_object_put(request_data_json); return; out: return; } /* * fn int get_realtime_info_from_cloud(struct realtime_weather_info_struct *realtime_weather_info, * char *device_token, char *url_prefix) * details 从云端获取当日天气数据并解析 * * param[in] struct realtime_weather_info_struct *realtime_weather_info 存储当日天气数据结构体 * char *device_token 从云端获取的device token * char *url_prefix 云端请求天气数据url前缀 * param[out] * * return ret 0表示获取数据成功,-1表示失败 * * note */ int get_realtime_info_from_cloud(struct realtime_weather_info_struct *realtime_weather_info, char *device_token, char *url_prefix) { int ret = -1; // int ret_post = 0; char request_url[128] = {0}; char request_header[64] = {0}; char tmpstr[40] = {0}; char request_data[512] = {0}; char *response = ""; st_http_resinfo httpResInfo; json_object* response_json = NULL; json_object* errorcode = NULL; json_object* message = NULL; json_object* result = NULL; json_object* temperature = NULL; json_object* temperatureMax = NULL; json_object* temperatureMin = NULL; json_object* weatherType = NULL; int errorcode_data = -1; const char* message_data = NULL; int temperature_data = -1; int temperatureMax_data = -1; int temperatureMin_data = -1; const char* weatherType_data = NULL; if (realtime_weather_info == NULL || device_token == NULL || url_prefix == NULL) { ERR("params error"); ret = -1; goto exit; } memset(&httpResInfo, 0, sizeof(st_http_resinfo)); sprintf(request_url, "%s%s", url_prefix, REALTIME_URL_POSTFIX); set_weather_cloud_request_data(device_token, request_data); //get post result cloud_https_post(request_url, request_header, request_data, &response, &httpResInfo); DEBUG("httpResInfo.status_code:%ld",httpResInfo.status_code); DEBUG("response:%s",response); if (response && httpResInfo.status_code == 200) { response_json = json_tokener_parse(response); errorcode = json_object_object_get(response_json, "code"); errorcode_data = json_object_get_int(errorcode); if (0 != errorcode_data) { weather_errorcode = errorcode_data; sprintf(tmpstr, "get weather info errorcode:%d", errorcode_data); uci_set_option("global", "error", tmpstr); ret = -1; goto exit; } message = json_object_object_get(response_json, "message"); result = json_object_object_get(response_json, "result"); temperature = json_object_object_get(result, "temperature"); temperatureMax = json_object_object_get(result, "temperatureMax"); temperatureMin = json_object_object_get(result, "temperatureMin"); weatherType = json_object_object_get(result, "weatherType"); message_data = json_object_get_string(message); temperature_data = json_object_get_int(temperature); temperatureMax_data = json_object_get_int(temperatureMax); temperatureMin_data = json_object_get_int(temperatureMin); weatherType_data = json_object_get_string(weatherType); if (0 == errorcode_data && message_data && weatherType_data) { DEBUG("errorcode : %d", errorcode_data); DEBUG("message : %s", message_data); DEBUG("temperature : %d", temperature_data); DEBUG("temperatureMax : %d", temperatureMax_data); DEBUG("temperatureMin : %d", temperatureMin_data); DEBUG("weatherType : %s", weatherType_data); // tmpstr = uci_get_unit(); // DEBUG("unit:%s",tmpstr); if (0 == strcmp(uci_get_unit(),"centigrade")) { realtime_weather_info->temperature = (temperature_data - 32) / 1.8; realtime_weather_info->temperatureMax = (temperatureMax_data -32) / 1.8; realtime_weather_info->temperatureMin = (temperatureMin_data - 32) / 1.8; } else { realtime_weather_info->temperature = temperature_data; realtime_weather_info->temperatureMax = temperatureMax_data; realtime_weather_info->temperatureMin = temperatureMin_data; } sprintf(realtime_weather_info->weatherType, "%s", weatherType_data); weather_errorcode = errorcode_data; memcpy(weather_message, message_data, strlen(message_data)); ret = 0; } } else { uci_set_option("global", "error", "cloud_https_post failed"); ret = -1; } exit: json_object_put(response_json); json_object_put(errorcode); json_object_put(message); json_object_put(result); json_object_put(temperature); json_object_put(temperatureMax); json_object_put(temperatureMin); json_object_put(weatherType); return ret; } /* * fn int get_forecast_info_from_cloud(struct forecast_weather_info_struct *forecast_weather_info, * char *device_token, char *url_prefix) * details 从云端获取未来三天天气数据并解析 * * param[in] struct forecast_weather_info_struct *forecast_weather_info 存储未来三天天气数据结构体 * char *device_token 从云端获取的device token * char *url_prefix 云端请求天气数据url前缀 * param[out] * * return ret 0表示获取数据成功,-1表示失败 * * note */ int get_forecast_info_from_cloud(struct forecast_weather_info_struct *forecast_weather_info, char *device_token, char *url_prefix) { int ret = -1; // int ret_post = 0; int i = 0; char request_url[128] = {0}; char request_header[64] = {0}; char tmpstr[40] = {0}; char request_data[512] = {0}; char *response = NULL; st_http_resinfo httpResInfo; json_object* response_json = NULL; json_object* errorcode = NULL; json_object* message = NULL; json_object* result = NULL; json_object* forecastList = NULL; json_object* ListItem = NULL; json_object* temperatureMax = NULL; json_object* temperatureMin = NULL; json_object* dayWeatherType = NULL; json_object* nightWeatherType = NULL; int errorcode_data = -1; const char* message_data = NULL; int temperatureMax_data = -1; int temperatureMin_data = -1; const char* dayWeatherType_data = NULL; const char* nightWeatherType_data = NULL; if (forecast_weather_info == NULL || device_token == NULL || url_prefix == NULL) { ERR("params error"); ret = -1; goto exit; } memset(&httpResInfo, 0, sizeof(st_http_resinfo)); sprintf(request_url, "%s%s", url_prefix, FORECASTS_URL_POSTFIX); set_weather_cloud_request_data(device_token, request_data); //get post result cloud_https_post(request_url, request_header, request_data, &response, &httpResInfo); DEBUG("httpResInfo.status_code:%ld",httpResInfo.status_code); DEBUG("response:%s",response); if (response && httpResInfo.status_code == 200) { response_json = json_tokener_parse(response); errorcode = json_object_object_get(response_json, "code"); errorcode_data = json_object_get_int(errorcode); if (0 != errorcode_data) { weather_errorcode = errorcode_data; sprintf(tmpstr, "get weather info errorcode:%d", errorcode_data); uci_set_option("global", "error", tmpstr); ret = -1; goto exit; } message = json_object_object_get(response_json, "message"); result = json_object_object_get(response_json, "result"); forecastList = json_object_object_get(result, "forecastList"); message_data = json_object_get_string(message); if (0 == errorcode_data && message_data) { DEBUG("errorcode : %d", errorcode_data); DEBUG("message : %s", message_data); for ( i = 0; i < 3; i++) { ListItem = json_object_array_get_idx(forecastList,i); temperatureMax = json_object_object_get(ListItem, "temperatureMax"); temperatureMin = json_object_object_get(ListItem, "temperatureMin"); dayWeatherType = json_object_object_get(ListItem, "dayWeatherType"); nightWeatherType = json_object_object_get(ListItem, "nightWeatherType"); temperatureMax_data = json_object_get_int(temperatureMax); temperatureMin_data = json_object_get_int(temperatureMin); dayWeatherType_data = json_object_get_string(dayWeatherType); nightWeatherType_data = json_object_get_string(nightWeatherType); DEBUG("temperatureMax : %d", temperatureMax_data); DEBUG("temperatureMin : %d", temperatureMin_data); DEBUG("dayWeatherType : %s", dayWeatherType_data); DEBUG("nightWeatherType : %s", nightWeatherType_data); if (dayWeatherType_data && nightWeatherType_data) { // tmpstr = uci_get_unit(); // DEBUG("unit:%s",tmpstr); if (0 == strcmp(uci_get_unit(),"centigrade")) { forecast_weather_info[i].temperatureMax = (temperatureMax_data - 32) / 1.8; forecast_weather_info[i].temperatureMin = (temperatureMin_data - 32) / 1.8; } else { forecast_weather_info[i].temperatureMax = temperatureMax_data; forecast_weather_info[i].temperatureMin = temperatureMin_data; } sprintf(forecast_weather_info[i].dayWeatherType, "%s", dayWeatherType_data); sprintf(forecast_weather_info[i].nightWeatherType, "%s", nightWeatherType_data); } } weather_errorcode = errorcode_data; memcpy(weather_message, message_data, strlen(message_data)); ret = 0; } } else { uci_set_option("global", "error", "cloud_https_post failed"); ret = -1; } exit: json_object_put(response_json); json_object_put(errorcode); json_object_put(message); json_object_put(result); json_object_put(forecastList); json_object_put(ListItem); json_object_put(temperatureMax); json_object_put(temperatureMin); json_object_put(dayWeatherType); json_object_put(nightWeatherType); return ret; } /* * fn static int update_weather_url(void) * details 更新天气数据 * * param[in] * param[out] * * return 0表示获取数据成功,-1表示失败 * * note */ static int update_weather_url(void) { char device_token[MAX_TOKEN_LEN] = {0}; char cloud_weather_url[MAX_URL_LEN] = {0}; int i = 0; /* init */ realtime_weather_info.temperature = 0; realtime_weather_info.temperatureMax = 0; realtime_weather_info.temperatureMin = 0; memset(realtime_weather_info.weatherType, 0, sizeof(realtime_weather_info.weatherType)); for ( i = 0; i < 3; i++) { forecast_weather_info[i].temperatureMax = 0; forecast_weather_info[i].temperatureMin = 0; memset(forecast_weather_info[i].dayWeatherType, 0, sizeof(forecast_weather_info[i].dayWeatherType)); memset(forecast_weather_info[i].nightWeatherType, 0, sizeof(forecast_weather_info[i].nightWeatherType)); } /* online request */ if (0 == (get_token_url(device_token, cloud_weather_url))) { /* get_realtime_info_from_cloud */ if (0 == get_realtime_info_from_cloud(&realtime_weather_info, device_token, cloud_weather_url)) { weather_ubus_update_event_generate(0); if (1 != uci_renew(0)) { ERR("set_realtime_info_to_uci fail"); uci_set_option("global", "error", "set_realtime_info_to_uci fail"); return -1; } DEBUG("get_realtime_info_from_cloud succeed"); } else { WARNING("get_realtime_info_from_cloud error"); return -1; } /* get_forecast_info_from_cloud */ if (0 == get_forecast_info_from_cloud(forecast_weather_info, device_token, cloud_weather_url)) { weather_ubus_update_event_generate(1); if (1 != uci_renew(1)) { ERR("set_forecast_info_to_uci fail"); uci_set_option("global", "error", "set_forecast_info_to_uci fail"); return -1; } DEBUG("get_forecast_info_from_cloud succeed"); } else { WARNING("get_forecast_info_from_cloud error"); return -1; } } else { uci_set_option("global", "error", "get_token_url error"); ERR("get_token_url error"); return -1; } // /* offline test*/ // (void)device_token; // (void)cloud_weather_url; // realtime_weather_info.temperature = 70; // realtime_weather_info.temperatureMax = 90; // realtime_weather_info.temperatureMin = 50; // if (0 == strcmp(uci_get_unit(),"centigrade")) // { // realtime_weather_info.temperature = (realtime_weather_info.temperature - 32) / 1.8; // realtime_weather_info.temperatureMax = (realtime_weather_info.temperatureMax -32) / 1.8; // realtime_weather_info.temperatureMin = (realtime_weather_info.temperatureMin - 32) / 1.8; // } // sprintf(realtime_weather_info.weatherType, "%s", "clear"); // weather_errorcode = 0; // memcpy(weather_message,"none",sizeof("none")); // weather_ubus_update_event_generate(0); // if (1 != uci_renew(0)) // { // ERR("set_realtime_info_to_uci fail"); // return -1; // } // for ( i = 0; i < 3; i++) // { // forecast_weather_info[i].temperatureMax = 91 + i; // forecast_weather_info[i].temperatureMin = 51 + i; // if (0 == strcmp(uci_get_unit(),"centigrade")) // { // forecast_weather_info[i].temperatureMax = (forecast_weather_info[i].temperatureMax - 32) / 1.8; // forecast_weather_info[i].temperatureMin = (forecast_weather_info[i].temperatureMin - 32) / 1.8; // } // sprintf(forecast_weather_info[i].dayWeatherType, "%s", "clear"); // sprintf(forecast_weather_info[i].nightWeatherType, "%s", "rain"); // } // weather_errorcode = 0; // memcpy(weather_message,"none",sizeof("none")); // weather_ubus_update_event_generate(1); // if (1 != uci_renew(1)) // { // ERR("set_forecast_info_to_uci fail"); // return -1; // } uci_set_option("global", "error", "weather info update success"); return 0; } /**********************************************uci相关函数******************************************/ /* * fn static void config_free(void) * details uci变量释放 * * param[in] * param[out] * * return * * note */ static void config_free(void) { if (uci_weather) { uci_unload(uci_ctx, uci_weather); uci_weather = NULL; } if (uci_ctx) { uci_free_context(uci_ctx); uci_ctx = NULL; } } /* * fn static struct uci_package *config_init_package(char *config) * details 获取uci文件package * * param[in] * param[out] * * return * * note */ static struct uci_package *config_init_package(char *config) { struct uci_package *p = NULL; if (!uci_ctx) { /* 申请uci上下文结构uci_ctx */ uci_ctx = uci_alloc_context(); // uci_ctx->flags &= ~UCI_FLAG_STRICT; } else { /* 查找config文件 */ p = uci_lookup_package(uci_ctx, config); if (p) { uci_unload(uci_ctx, p); } DEBUG("S:uci_unload"); } /* 加载配置到内存 */ if ( UCI_OK != uci_load(uci_ctx, config, &p) ) { p = NULL; DEBUG("S:uci load error"); } return p; } /* * fn static int config_alloc(void) * details 获取uci文件package,地址保存到全局变量uci_weather中 * * param[in] * param[out] * * return * * note */ static int config_alloc(void) { uci_weather = config_init_package("weather"); if (!uci_weather) { ERR("S:Failed to load weather config"); return 0; } DEBUG("S:succeed to load weather config"); return 1; } /* * fn static int uci_init(void) * details uci初始化 * * param[in] * param[out] * * return * * note */ static int uci_init(void) { struct uci_section *tmp_sec; /* 获取uci配置文件 */ if( !config_alloc()) { ERR("S:config_alloc error"); config_free(); return 0; } /* 检查uci配置文件中的section */ tmp_sec = uci_lookup_section(uci_ctx, uci_weather, "global"); if ( !tmp_sec) { ERR("S:lookup global section failed"); config_free(); return 0; } tmp_sec = uci_lookup_section(uci_ctx, uci_weather, "realtime"); if ( !tmp_sec) { ERR("S:lookup realtime section failed"); config_free(); return 0; } tmp_sec = uci_lookup_section(uci_ctx, uci_weather, "forecast"); if ( !tmp_sec) { ERR("S:lookup forecast section failed"); config_free(); return 0; } tmp_sec = uci_lookup_section(uci_ctx, uci_weather, "tomorrow"); if ( !tmp_sec) { ERR("S:lookup forecast1 section failed"); config_free(); return 0; } tmp_sec = uci_lookup_section(uci_ctx, uci_weather, "2_days_later"); if ( !tmp_sec) { ERR("S:lookup forecast2 section failed"); config_free(); return 0; } tmp_sec = uci_lookup_section(uci_ctx, uci_weather, "3_days_later"); if ( !tmp_sec) { ERR("S:lookup forecast3 section failed"); config_free(); return 0; } return 1; } /* * fn static int uci_set_option(char *uci_section, char *uci_option, char *uci_value) * details 配置uci配置文件option * * param[in] char *uci_section section名 * char *uci_option option的key, * char *uci_value option的value * param[out] * * return * * note */ static int uci_set_option(char *uci_section, char *uci_option, char *uci_value) { int ret = 0; struct uci_ptr ptr ={ .package = "weather", .section = uci_section, .option = uci_option, .value = uci_value }; /* 配置uci配置文件option,key=uci_option,value=uci_value*/ ret = uci_set(uci_ctx, &ptr); if( UCI_OK != ret) { ERR("S:set %s failed",uci_option); return 0; } // DEBUG("S:set %s ok",uci_option); /* 保存配置 */ uci_save(uci_ctx, ptr.p); uci_commit(uci_ctx, &ptr.p, false); return 1; } /* * fn int uci_get_locationkey(void) * details 从uci配置文件中读取locationkey * * param[in] * param[out] * * return key 从uci配置文件中读取的locationkey * * note */ int uci_get_locationkey(void) { int key = 0; const char *key_str = NULL; struct uci_context *tmpCtx = NULL; struct uci_package *tmppkg = NULL; struct uci_section *tmpsec = NULL; tmpCtx = uci_alloc_context(); if ( UCI_OK != uci_load(tmpCtx, "weather", &tmppkg) ) { uci_set_option("global", "error", "uci_load weather error"); ERR("S:uci load error"); key = -1; goto exit; } tmpsec = uci_lookup_section(tmpCtx, tmppkg, "global"); if ( !tmpsec) { uci_set_option("global", "error", "lookup global section failed"); ERR("S:lookup global section failed"); key = -1; goto exit; } key_str = uci_lookup_option_string(tmpCtx, tmpsec, "location_key"); if(!key_str) { uci_set_option("global", "error", "lookup location_key option failed"); ERR("S:lookup location_key option failed"); key = -1; goto exit; } key = atoi(key_str); DEBUG("uci_get_option location_key:%d",key); exit: uci_unload(tmpCtx, tmppkg); uci_free_context(tmpCtx); return key; } /* * fn const char *uci_get_unit(void) * details 从uci配置文件中读取temperature_unit * * param[in] * param[out] * * return unit_str 从uci配置文件中读取的temperature_unit * * note */ const char *uci_get_unit(void) { const char *unit_str = NULL; struct uci_context *tmpCtx = NULL; struct uci_package *tmppkg = NULL; struct uci_section *tmpsec = NULL; tmpCtx = uci_alloc_context(); if ( UCI_OK != uci_load(tmpCtx, "weather", &tmppkg) ) { uci_set_option("global", "error", "uci_load weather error"); ERR("S:uci load error"); goto exit; } tmpsec = uci_lookup_section(tmpCtx, tmppkg, "global"); if ( !tmpsec) { uci_set_option("global", "error", "lookup global section failed"); ERR("S:lookup global section failed"); goto exit; } unit_str = uci_lookup_option_string(tmpCtx, tmpsec, "temperature_unit"); if(!unit_str) { uci_set_option("global", "error", "lookup unit option failed"); ERR("S:lookup unit option failed"); goto exit; } DEBUG("uci_get_option unit:%s",unit_str); exit: uci_unload(tmpCtx, tmppkg); uci_free_context(tmpCtx); return unit_str; } /* * fn static void uci_renew(int flag) * details 将从云端拿到的天气数据写入uci配置文件, * * param[in] int flag 为0时表示写入当日天气数据,为1时表示写入未来三天天气数据 * param[out] * * return 0表示写入失败,1表示写入成功 * * note */ static int uci_renew(int flag) { time_t timep; struct tm date; // char time_cu[10] = ""; char section[20] = ""; char tmpstr[20] = ""; int i = 0; /* 获取当前unix时间 */ time(&timep); /* 配置uci配置文件对应option */ if (0 == flag) { /* 更新实时天气信息 */ date = * (localtime(&timep)); if (1 != uci_set_option("realtime", "errorcode", Int2String(weather_errorcode,tmpstr))) { return 0; } if (1 != uci_set_option("realtime", "message", weather_message)) { return 0; } if (1 != uci_set_option("realtime", "time_renew", Int2String((int)timep,tmpstr))) { return 0; } if (1 != uci_set_option("realtime", "month", Int2String(date.tm_mon + 1,tmpstr))) { return 0; } if (1 != uci_set_option("realtime", "day", Int2String(date.tm_mday,tmpstr))) { return 0; } if (1 != uci_set_option("realtime", "temperature", Int2String(realtime_weather_info.temperature,tmpstr))) { return 0; } if (1 != uci_set_option("realtime", "temperatureMax", Int2String(realtime_weather_info.temperatureMax,tmpstr))) { return 0; } if (1 != uci_set_option("realtime", "temperatureMin", Int2String(realtime_weather_info.temperatureMin,tmpstr))) { return 0; } if (1 != uci_set_option("realtime", "weatherType", realtime_weather_info.weatherType)) { return 0; } DEBUG("S:realtime weather uci renew time:%ld", timep); } else { /* 更新预报天气信息 */ if (1 != uci_set_option("forecast", "errorcode", Int2String(weather_errorcode,tmpstr))) { return 0; } if (1 != uci_set_option("forecast", "message", weather_message)) { return 0; } if (1 != uci_set_option("forecast", "time_renew", Int2String((int)timep,tmpstr))) { return 0; } for (i = 0; i < 3; i++) { timep += 86400; /* 调整到后一天同一时刻 */ date = * (localtime(&timep)); if (0 == i) { sprintf(section,"tomorrow"); } else { sprintf(section,"%d_days_later",i + 1); } if (1 != uci_set_option(section, "temperatureMax", Int2String(forecast_weather_info[i].temperatureMax,tmpstr))) { return 0; } if (1 != uci_set_option(section, "temperatureMin", Int2String(forecast_weather_info[i].temperatureMin,tmpstr))) { return 0; } if (1 != uci_set_option(section, "dayWeatherType", forecast_weather_info[i].dayWeatherType)) { return 0; } if (1 != uci_set_option(section, "nightWeatherType", forecast_weather_info[i].nightWeatherType)) { return 0; } if (1 != uci_set_option(section, "month", Int2String(date.tm_mon + 1,tmpstr))) { return 0; } if (1 != uci_set_option(section, "day", Int2String(date.tm_mday,tmpstr))) { return 0; } } DEBUG("S:forecast weather uci renew time:%ld", timep - 86400 * 3); } return 1; } /**********************************************定时控制函数*****************************************/ /* * fn static void weather_timer_cb(struct uloop_timeout *timer) * details 定时更新天气数据,renew_interval控制下次更新时间间隔 * * param[in] * param[out] * * return * * note */ static void weather_timer_cb(struct uloop_timeout *timer) { if (0 != update_weather_url()) { ERR("S:update_weather_url failed"); if (DEFAULT_INTERVAL == renew_interval) { if (-20652 == weather_errorcode) { system("rm /tmp/cloud/cloud_token_weather"); /* devicetoken失效 */ renew_interval = FAST_INTERVAL; /* 10s后重试 */ } else { renew_interval = MID_INTERVAL; /* 5min后重试 */ } } else if(DEFAULT_INTERVAL > renew_interval * 2) { renew_interval *= 2; /* 重试时间*2 */ } else { renew_interval = DEFAULT_INTERVAL + 1; /* 最高时间间隔6h+1s,多1s防止误判,否则再次失败renew_interval又会缩短 */ } } else { renew_interval = DEFAULT_INTERVAL; /* 成功后时间恢复6h */ } DEBUG("Period CallBack"); uloop_timeout_set(timer, renew_interval * 1000); } /**************************************************************************************************/ /* PUBLIC_FUNCTIONS */ /**************************************************************************************************/ /**************************************************************************************************/ /* GLOBAL_FUNCTIONS */ /**************************************************************************************************/ int main() { char *ubus_socket = NULL; char seed; /* 随机种子 */ memset(&timer, 0, sizeof(timer)); /* ubus初始化 */ uloop_init(); if (-1 == weather_ubus_init(ubus_socket)) { ERR("S:weather_ubus_init failed"); } /* uci初始化 */ if (0 == uci_init()) { ERR("S:uci_init failed"); } /* 启动随机延迟 */ srand((unsigned int)&seed); sleep(rand() % 300); DEBUG("random sleep"); /* 配置定时更新函数 */ timer.cb = weather_timer_cb; uloop_timeout_set(&timer, 0); /* uloop启动 */ DEBUG("S:uloop_run start"); uloop_run(); DEBUG("S:uloop_run end"); /*uci变量释放*/ config_free(); /* curl释放*/ curl_global_cleanup(); /* ubus释放*/ weather_ubus_deinit(); uloop_done(); DEBUG("S:uloop_done"); return 0; }
09-11
void *Display_WeatherRoutine(void *arg) { pthread_cleanup_push(Display_CleanUpHandler, "weather thread exit"); //socket int sock_fd = socket(AF_INET, SOCK_STREAM, 0); if(sock_fd == -1) { perror("socket error"); return; } //get addr by domain name struct hostent *server_info = gethostbyname(WEATHER_SERVER_NAME); if(server_info == NULL) { perror("gethostbyname error"); return; } int i = 0; while (server_info->h_addr_list[i] != NULL) { printf("%s\n",inet_ntoa(*(struct in_addr *)(server_info->h_addr_list[i]))); i++; } //connect struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(HTTP_DEF_PORT); server_addr.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr *)(server_info->h_addr_list[0]))); if(connect(sock_fd, (struct sockaddr *)&server_addr,sizeof(server_addr))) { perror("bind error"); return; } else { printf("connect ok\n"); } char reqbuf[1024] = {0}; while (1) { memset(reqbuf,0,sizeof(reqbuf)); memset(weather_info,0,sizeof(weather_info)); sprintf(reqbuf,"GET https://restapi.amap.com/v3/weather/weatherInfo?city=%s&key=%s HTTP/1.1\r\n" "Host:%s\r\n" "\r\n",CITY,WEATHER_KEY,WEATHER_SERVER_NAME); send(sock_fd,reqbuf,strlen(reqbuf),0); char recvbuf[1024] = {0}; recv(sock_fd,recvbuf,sizeof(recvbuf),0); //printf("%s\n",recvbuf); char *bodybuf; bodybuf = strstr(recvbuf,"\r\n\r\n")+4; cJSON *body_json = cJSON_Parse(bodybuf); //printf("%s\n",cJSON_Print(body_json)); cJSON *lives = cJSON_GetObjectItem(body_json,"lives"); //printf("%s\n",cJSON_Print(lives)); cJSON *live = NULL; cJSON_ArrayForEach(live,lives) { // cJSON *temperature = cJSON_GetObjectItem(live,"temperature"); // printf("temp:%s\n",temperature->valuestring); sprintf(weather_info,"%s%s %s %s风 %s度", cJSON_GetObjectItem(live,"province")->valuestring, cJSON_GetObjectItem(live,"city")->valuestring, cJSON_GetObjectItem(live,"weather")->valuestring, cJSON_GetObjectItem(live,"winddirection")->valuestring, cJSON_GetObjectItem(live,"temperature")->valuestring); } cJSON_Delete(body_json); printf("%s\n",weather_info); sleep(1);//20分钟更新一次 } pthread_cleanup_pop(1); }这段代码循环到第二次接收到的数据为空,导致段错误 是什么原因
07-13
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> // 同学信息结构体 typedef struct Student { char name[50]; char gender; char phone[15]; char email[50]; char city[50]; struct Student* next; } Student; // 全局链表头指针 Student* head = NULL; // 创建新同学节点 Student* create_student() { Student* new_student = (Student*)malloc(sizeof(Student)); if (new_student == NULL) { printf("内存分配失败\n"); return NULL; } printf("请输入姓名: "); scanf("%s", new_student->name); printf("请输入性别(M/F): "); scanf(" %c", &new_student->gender); printf("请输入电话号码: "); scanf("%s", new_student->phone); printf("请输入邮箱: "); scanf("%s", new_student->email); printf("请输入所在城市: "); scanf("%s", new_student->city); new_student->next = NULL; return new_student; } // 添加同学到通讯录 void add_student() { Student* new_student = create_student(); if (new_student == NULL) return; if (head == NULL) { head = new_student; } else { Student* temp = head; while (temp->next != NULL) { temp = temp->next; } temp->next = new_student; } printf("同学信息添加成功!\n"); } // 删除同学信息 void delete_student(const char* name) { if (head == NULL) { printf("通讯录为空!\n"); return; } Student* current = head; Student* previous = NULL; while (current != NULL) { if (strcmp(current->name, name) == 0) { if (previous == NULL) { head = current->next; } else { previous->next = current->next; } free(current); printf("删除成功!\n"); return; } previous = current; current = current->next; } printf("未找到该同学: %s\n", name); } // 修改同学信息 void update_student(const char* name) { Student* current = head; while (current != NULL) { if (strcmp(current->name, name) == 0) { printf("请输入新的电话号码: "); scanf("%s", current->phone); printf("请输入新的邮箱: "); scanf("%s", current->email); printf("请输入新的所在城市: "); scanf("%s", current->city); printf("信息更新成功!\n"); return; } current = current->next; } printf("未找到该同学: %s\n", name); } // 打印同学信息 void print_student(Student* student) { printf("姓名: %-15s 性别: %c 电话: %-15s 邮箱: %-20s 城市: %s\n", student->name, student->gender, student->phone, student->email, student->city); } // 按姓名查询(线性查找) Student* search_by_name(const char* name) { Student* current = head; while (current != NULL) { if (strcmp(current->name, name) == 0) { return current; } current = current->next; } return NULL; } // 按城市查询 void search_by_city(const char* city) { Student* current = head; int found = 0; printf("\n--- 在 %s 的同学 ---\n", city); while (current != NULL) { if (strcmp(current->city, city) == 0) { print_student(current); found = 1; } current = current->next; } if (!found) { printf("未找到该城市的同学\n"); } } // 折半查找辅助函数(将链表转为数组) int convert_list_to_array(Student*** array) { int count = 0; Student* current = head; // 计算链表长度 while (current != NULL) { count++; current = current->next; } if (count == 0) return 0; // 分配数组内存 *array = (Student**)malloc(count * sizeof(Student*)); if (*array == NULL) { printf("内存分配失败\n"); return 0; } // 填充数组 current = head; for (int i = 0; i < count; i++) { (*array)[i] = current; current = current->next; } return count; } // 按姓名折半查找 void binary_search_by_name(const char* name) { Student** array = NULL; int count = convert_list_to_array(&array); if (count == 0) { printf("通讯录为空!\n"); return; } // 折半查找 int left = 0, right = count - 1; while (left <= right) { int mid = left + (right - left) / 2; int cmp = strcmp(array[mid]->name, name); if (cmp == 0) { printf("\n找到同学:\n"); print_student(array[mid]); free(array); return; } else if (cmp < 0) { left = mid + 1; } else { right = mid - 1; } } printf("未找到该同学: %s\n", name); free(array); } // 冒泡排序按姓名 void bubble_sort_by_name() { if (head == NULL || head->next == NULL) return; int swapped; Student* ptr1; Student* lptr = NULL; do { swapped = 0; ptr1 = head; while (ptr1->next != lptr) { if (strcmp(ptr1->name, ptr1->next->name) > 0) { // 交换节点数据(实际应用中应交换节点指针) Student temp = *ptr1; *ptr1 = *(ptr1->next); *(ptr1->next) = temp; // 保持next指针正确 temp.next = ptr1->next; ptr1->next = temp.next; ptr1->next->next = temp.next->next; swapped = 1; } ptr1 = ptr1->next; } lptr = ptr1; } while (swapped); printf("已按姓名排序!\n"); } // 显示所有同学 void display_all() { if (head == NULL) { printf("通讯录为空!\n"); return; } printf("\n--- 所有同学信息 ---\n"); Student* current = head; while (current != NULL) { print_student(current); current = current->next; } } // 释放链表内存 void free_list() { Student* current = head; while (current != NULL) { Student* next = current->next; free(current); current = next; } head = NULL; } // 主菜单 int main() { int choice; char name[50], city[50]; while (1) { printf("\n=== 同学通讯录管理系统 ===\n"); printf("1. 添加同学信息\n"); printf("2. 删除同学信息\n"); printf("3. 修改同学信息\n"); printf("4. 按姓名查询(线性查找)\n"); printf("5. 按城市查询\n"); printf("6. 按姓名查询(折半查找)\n"); printf("7. 按姓名排序(冒泡排序)\n"); printf("8. 显示所有同学\n"); printf("9. 退出系统\n"); printf("请选择操作: "); scanf("%d", &choice); switch (choice) { case 1: {add_student(); break;} case 2: {printf("请输入要删除的同学姓名: "); scanf("%s", name); delete_student(name); break;} case 3: {printf("请输入要修改的同学姓名: "); scanf("%s", name); update_student(name); break;} case 4: {printf("请输入要查询的同学姓名: "); scanf("%s", name); Student* result = search_by_name(name); if (result != NULL) { printf("\n找到同学:\n"); print_student(result); } else { printf("未找到该同学\n"); } break;} case 5: {printf("请输入要查询的城市: "); scanf("%s", city); search_by_city(city); break;} case 6: {printf("请输入要查询的同学姓名: "); scanf("%s", name); binary_search_by_name(name); break;} case 7: {bubble_sort_by_name(); break;} case 8: {display_all(); break;} case 9: {free_list(); printf("系统已退出!\n"); exit(0);} default: {printf("无效选择,请重新输入!\n");} } } return 0; } 增加这里的按同学姓名排序的排序方法功能,并按照上述格式填入其中,输出完整代码
06-24
#ifdef SQLITE_ENABLE_FTS5 /* Register any built-in FTS5 module before loading the automatic ** extensions. This allows automatic extensions to register FTS5 ** tokenizers and auxiliary functions. */ if( !db->mallocFailed && rc==SQLITE_OK ){ rc = sqlite3Fts5Init(db); } #endif /* Load automatic extensions - extensions that have been registered ** using the sqlite3_automatic_extension() API. */ if( rc==SQLITE_OK ){ sqlite3AutoLoadExtensions(db); rc = sqlite3_errcode(db); if( rc!=SQLITE_OK ){ goto opendb_out; } } #ifdef SQLITE_ENABLE_FTS1 if( !db->mallocFailed ){ extern int sqlite3Fts1Init(sqlite3*); rc = sqlite3Fts1Init(db); } #endif #ifdef SQLITE_ENABLE_FTS2 if( !db->mallocFailed && rc==SQLITE_OK ){ extern int sqlite3Fts2Init(sqlite3*); rc = sqlite3Fts2Init(db); } #endif #ifdef SQLITE_ENABLE_FTS3 /* automatically defined by SQLITE_ENABLE_FTS4 */ if( !db->mallocFailed && rc==SQLITE_OK ){ rc = sqlite3Fts3Init(db); } #endif #ifdef SQLITE_ENABLE_ICU if( !db->mallocFailed && rc==SQLITE_OK ){ rc = sqlite3IcuInit(db); } #endif #ifdef SQLITE_ENABLE_RTREE if( !db->mallocFailed && rc==SQLITE_OK){ rc = sqlite3RtreeInit(db); } #endif #ifdef SQLITE_ENABLE_DBSTAT_VTAB if( !db->mallocFailed && rc==SQLITE_OK){ rc = sqlite3DbstatRegister(db); } #endif #ifdef SQLITE_ENABLE_JSON1 if( !db->mallocFailed && rc==SQLITE_OK){ rc = sqlite3Json1Init(db); } #endif /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking ** mode. Doing nothing at all also makes NORMAL the default. */ #ifdef SQLITE_DEFAULT_LOCKING_MODE db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE; sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt), SQLITE_DEFAULT_LOCKING_MODE); #endif if( rc ) sqlite3Error(db, rc); /* Enable the lookaside-malloc subsystem */ setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, sqlite3GlobalConfig.nLookaside); sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT); opendb_out: if( db ){ assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 ); sqlite3_mutex_leave(db->mutex); } rc = sqlite3_errcode(db); assert( db!=0 || rc==SQLITE_NOMEM ); if( rc==SQLITE_NOMEM ){ sqlite3_close(db); db = 0; }else if( rc!=SQLITE_OK ){ db->magic = SQLITE_MAGIC_SICK; } *ppDb = db; #ifdef SQLITE_ENABLE_SQLLOG if( sqlite3GlobalConfig.xSqllog ){ /* Opening a db handle. Fourth parameter is passed 0. */ void *pArg = sqlite3GlobalConfig.pSqllogArg; sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0); } #endif #if defined(SQLITE_HAS_CODEC) if( rc==SQLITE_OK ){ const char *zHexKey = sqlite3_uri_parameter(zOpen, "hexkey"); if( zHexKey && zHexKey[0] ){ u8 iByte; int i; char zKey[40]; for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zHexKey[i]); i++){ iByte = (iByte<<4) + sqlite3HexToInt(zHexKey[i]); if( (i&1)!=0 ) zKey[i/2] = iByte; } sqlite3_key_v2(db, 0, zKey, i/2); } } #endif sqlite3_free(zOpen); return rc & 0xff;这段代码和上一段是同一个函数内部的,太长所以分段了,继续帮我分析
最新发布
09-19
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值