首页 > 系统相关 >Linux下C语言调用libcurl库获取天气预报信息

Linux下C语言调用libcurl库获取天气预报信息

时间:2023-09-09 10:06:52浏览次数:42  
标签:get libcurl object C语言 json weather Linux curl ptr


一、概述

当前文章介绍如何在Linux(Ubuntu)下使用C语言调用libcurl库获取天气预报的方法。通过HTTP GET请求访问百度天气API,并解析返回的JSON数据,可以获取指定城市未来7天的天气预报信息。

Linux下C语言调用libcurl库获取天气预报信息_获取天气预报

Linux下C语言调用libcurl库获取天气预报信息_json_02

二、设计思路

【1】使用libcurl库进行HTTP GET请求

  • 在代码中包含<curl/curl.h>头文件,以便使用libcurl库
  • 使用curl_easy_init()函数初始化curl
  • 设置请求选项,包括URL、写回调函数和写数据参数
  • 使用curl_easy_perform()函数执行请求

【2】编写回调函数,将响应数据存储在内存中

  • 定义一个结构体,包含存储响应数据的指针和长度
  • 在回调函数中将响应数据拷贝到内存中,并动态调整内存大小
  • 返回已拷贝的数据大小

【3】解析JSON数据

  • 使用json_tokener_parse()函数解析返回的JSON数据
  • 使用json_object_object_get_ex()函数获取指定字段的值
  • 使用json_object_array_length()函数获取数组长度
  • 使用json_object_array_get_idx()函数获取数组中的元素
  • 使用json_object_get_string()函数获取字符串值

【4】打印天气预报信息

  • 遍历获取到的天气预报数据,依次获取日期、天气和温度
  • 使用printf()函数打印每一天的天气预报信息

三、关键代码

以下是主要的代码片段:

// 定义回调函数,用于将响应数据存储在内存中
size_t write_callback(void *ptr, size_t size, size_t nmemb, void *stream) {
    // ...
}

// 子函数,用于获取指定城市未来7天的天气预报
int get_weather_forecast(const char *city) {
    // ...
}

int main() {
    const char *city = "your_city_code";
    int ret = get_weather_forecast(city);
    // ...
}

四、使用说明

【1】替换API密钥和城市代码:在示例代码中,将your_akyour_city_code替换为你自己的百度API密钥和城市代码。

【2】编译代码:使用合适的C编译器,如gcc,编译代码。

gcc -o download_program download_program.c -lcurl

【3】运行代码:在终端中运行生成的可执行文件。

./download_program

【4】查看天气预报:程序会打印出指定城市未来7天的天气预报信息。

五、完整代码

HTTP GET请求访问百度天气API,并解析返回的JSON数据获取需要的天气信息。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <json-c/json.h>

// 定义回调函数,用于将响应数据存储在内存中
size_t write_callback(void *ptr, size_t size, size_t nmemb, void *stream) {
    size_t realsize = size * nmemb;
    struct string *mem = (struct string *)stream;

    mem->ptr = realloc(mem->ptr, mem->len + realsize + 1);
    if (mem->ptr == NULL) {
        fprintf(stderr, "内存分配失败\n");
        return 0;
    }

    memcpy(&(mem->ptr[mem->len]), ptr, realsize);
    mem->len += realsize;
    mem->ptr[mem->len] = '\0';

    return realsize;
}

// 子函数,用于获取指定城市未来7天的天气预报
int get_weather_forecast(const char *city) {
    char url[256];
    sprintf(url, "https://api.map.baidu.com/weather/v1/?district_id=%s&ak=your_ak", city);

    CURL *curl = curl_easy_init();
    struct string response;
    response.ptr = malloc(1);
    response.len = 0;

    if (curl && response.ptr) {
        // 设置请求选项
        curl_easy_setopt(curl, CURLOPT_URL, url);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

        // 执行请求
        CURLcode res = curl_easy_perform(curl);
        if (res != CURLE_OK) {
            fprintf(stderr, "请求失败: %s\n", curl_easy_strerror(res));
            free(response.ptr);
            curl_easy_cleanup(curl);
            return -1;
        }

        // 解析JSON数据
        struct json_object *json = json_tokener_parse(response.ptr);
        if (json == NULL) {
            fprintf(stderr, "JSON解析失败\n");
            free(response.ptr);
            curl_easy_cleanup(curl);
            return -1;
        }

        // 解析天气预报
        struct json_object *result, *weather_data;
        json_object_object_get_ex(json, "result", &result);
        json_object_object_get_ex(result, "weather_data", &weather_data);

        int i;
        int num_days = json_object_array_length(weather_data);
        for (i = 0; i < num_days; i++) {
            struct json_object *day = json_object_array_get_idx(weather_data, i);
            const char *date, *weather, *temperature;
            date = json_object_get_string(json_object_object_get(day, "date"));
            weather = json_object_get_string(json_object_object_get(day, "weather"));
            temperature = json_object_get_string(json_object_object_get(day, "temperature"));

            printf("日期:%s\n天气:%s\n温度:%s\n\n", date, weather, temperature);
        }

        free(response.ptr);
        json_object_put(json);
    } else {
        fprintf(stderr, "初始化失败\n");
        if (response.ptr) {
            free(response.ptr);
        }
        if (curl) {
            curl_easy_cleanup(curl);
        }
        return -1;
    }

    curl_easy_cleanup(curl);
    return 0;
}

int main() {
    const char *city = "your_city_code";
    int ret = get_weather_forecast(city);
    if (ret == 0) {
        printf("天气预报获取成功!\n");
    } else {
        printf("天气预报获取失败!\n");
    }

    return 0;
}

在示例代码中,使用curl_easy_setopt函数设置HTTP GET请求的URL,并通过CURLOPT_WRITEFUNCTIONCURLOPT_WRITEDATA选项指定回调函数,将响应数据存储在内存中。

然后,使用json_tokener_parse函数解析返回的JSON数据,并提取其中的天气预报信息。通过json_object_object_getjson_object_array_get_idx等函数获取JSON对象和数组中的数据。

注意:代码中的URL中的YOUR_AKYOUR_CITY_CODE需要使用你自己的百度API密钥和城市代码替换。

通过调用get_weather_forecast函数,可以获取指定城市未来7天的天气预报并打印出来。

标签:get,libcurl,object,C语言,json,weather,Linux,curl,ptr
From: https://blog.51cto.com/u_11822586/7416960

相关文章

  • 运维工程师工作时最常用的20个Linux命令有哪些?建议收藏
    运维人员在管理和维护Linux系统时,需要经常使用一些常见的命令来完成各种任务。下面是20个运维高频使用的Linux命令及其示例。1、cd改变当前工作目录示例:进入“/var/log”目录:cd/var/log2、ls列出目录内容示例:列出当前目录内容:ls3、cat查看文件内容示例:查看“/var/......
  • Linux环境编程-库
    一、库:库文件是目标文件的集合,可以被其他代码调用,把代码封装成库文件后方便使用、方便管理,安全性高、保密性强静态库:就是目标文件的集合,当调用静态库时,编译器会把静态库的所有的二进制指令拷贝到最后的可执行文件中优点:运行速度比共享库要快,运行时不需要依赖静态库文件。(它......
  • Linux与Windows双系统,安装完linux后无法通过grub进入Windows的解决方法
    其中有提示,所以解决方案也非常明确Warning:os-proberwillnotbeexecutedtodetectotherbootablepartitions.SystemsonthemwillnotbeaddedtotheGRUBbootconfiguration.CheckGRUB_DISABLE_OS_PROBERdocumentationentry.可以参考:https://huaweicloud.cs......
  • 在 Linux 系统上安装主播软件
    捕获设置在顶层菜单中,我们选择“File”→“Settings”,然后我们选择“Output”来设置要生成的文件的选项。这里我们可以设置想要的音频和视频的比特率、新创建的文件的目标路径和文件格式。这上面还提供了粗略的质量设置。如果我们将顶部的输出模式从“Simple”更改为“A......
  • c语言学习之路--static的用法(笔记)
    1.static修饰局部变量时可以理解为将局部变量变为全局变量,如图:#include<stdio.h>voidtest(void){ inta=1; a++; printf("a的值为%d\n",a); }intmain(void){ inti=0; while(i<5){ i++; test(); } return0;}没有static时结果为a的值为2a的值为2......
  • linux开发环境配置
    1.jdk1.81.解压tar-zxvfjdk-8u381-linux-x64.tar.gz-C/usr/local/java2.环境配置##安装vimyum-yinstallvim##配置文件vim/etc/profileexportJAVA_HOME=/usr/local/java/jdk1.8.0_381exportPATH=$JAVA_HOME/bin:$PATHexportCLASSPATH=.:$JAVA_HOME/lib/dt.jar:......
  • C语言函数递归 --- 复习题(1)
    一.单选题:1.下列选项关于递归说法错误的是()A.存在限制条件,当满足限制条件时,递归停止B.每次递归调用后越来越接近递归的条件C.递归可以无限制递归下去D.递归层次太深容易出现栈溢出答案:C,这题错误的选项显而易见是C,我们之前将递归的时候就说过递归的两个要求,第一个是需要有限制条......
  • C语言-结构体、共用体,内存管理
    结构体结构体的定义及变量使用#include<stdio.h>#include<string.h>structstudent{charname[20];intage;charsex;}stu3;//定义结构体的同时定义结构体变量。此时是全局变量intmain(intargc,charconst*argv[]){structstudentstu1,s......
  • Linux系统文件夹权限以及shell外壳的理解
    文件是什么和文件权限的简单理解首先我们要知道对于Linux中的文件而言一个文件=属性+内容。并且对于一个操作系统的使用人员而言,一个文件具有三种权限,分别是可读,可写,可执行。并且操作系统对于每一个用户(除了root权限)对于一个文件而言会倍分成不同的组。对于文件的创建者而言,Linux......
  • 从零开始搭建EasyDarwin环境——linux系统开发环境nodejs的搭建
    EasyDarwin是目前比较热门的开源平台之一,上一篇我们给大家详细展示了搭建EasyDarwin环境前实现虚拟机Linux系统共享目录,本文我们将说明一下如何在Linux下搭建起nodejs环境。1.首先安装wgetyuminstall-ywget如果已经安装了可以跳过该步骤。2.下载nodejs最新的bin包可以在下载页......