本文作者:咔咔

如何在C语言中实现实时股价数据的获取与动态展示?

如何在C语言中实现实时股价数据的获取与动态展示?摘要: 我将为你提供一个完整、可运行的 C 语言项目,它能够:使用 libcurl 库从 Alpha Vantage 的免费 API 获取实时股票数据,使用 cJSON 库解析返回的 JS...

我将为你提供一个完整、可运行的 C 语言项目,它能够:

  1. 使用 libcurl 库从 Alpha Vantage 的免费 API 获取实时股票数据。
  2. 使用 cJSON 库解析返回的 JSON 格式数据。
  3. 将获取到的股价信息清晰地打印在控制台。
  4. 通过一个循环,每隔一段时间(10 秒)自动刷新数据,实现“实时”效果。

项目结构

你的项目文件可以这样组织:

stock_price_monitor/
├── main.c
├── Makefile
└── README.md

第 1 步:获取 API 密钥

你需要一个免费的股票数据 API,这里我们使用 Alpha Vantage,它提供免费的 API 调用额度。

  1. 访问 Alpha Vantage 官网 并注册一个免费账户。
  2. 注册后,你将获得一个 API 密钥(一串字符),XXXXXXXXXXXXXXXX

注意: 免费账户有调用频率限制(每分钟 5 次,每天 500 次),请勿滥用。


第 2 步:安装必要的库

你需要安装 libcurlcJSON,如果你使用的是基于 Debian/Ubuntu 的系统,可以使用以下命令:

# 安装 libcurl
sudo apt-get update
sudo apt-get install libcurl4-openssl-dev
# 安装 cJSON
sudo apt-get install libcjson-dev

对于 macOS (使用 Homebrew):

# 安装 libcurl
brew install curl
# 安装 cJSON
brew install cJSON

对于 Windows,下载预编译的库文件并配置你的开发环境(如 MinGW 或 Visual Studio)会更复杂一些,但原理相同。


第 3 步:编写 C 代码 (main.c)

这是项目的核心代码,代码中包含了详细的注释,解释了每一步的作用。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // for sleep()
// 包含 libcurl 和 cJSON 的头文件
#include <curl/curl.h>
#include <cjson/cJSON.h>
// 用于存储从 libcurl 获取的数据的回调函数
struct MemoryStruct {
  char *memory;
  size_t size;
};
// 回调函数:libcurl 会将接收到的数据块 append 到我们提供的 MemoryStruct 中
static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;
  char *ptr = realloc(mem->memory, mem->size + realsize + 1);
  if(!ptr) {
    /* out of memory! */
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }
  mem->memory = ptr;
  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;
  return realsize;
}
// 函数:从 Alpha Vantage API 获取并解析股价
void fetch_and_parse_stock(const char *api_key, const char *symbol) {
    CURL *curl;
    CURLcode res;
    // 初始化 libcurl 全局变量
    curl_global_init(CURL_GLOBAL_ALL);
    // 初始化一个 easy 会话
    curl = curl_easy_init();
    if(curl) {
        // 构建请求 URL
        char url[256];
        snprintf(url, sizeof(url), "https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=%s&apikey=%s", symbol, api_key);
        // 设置 URL
        curl_easy_setopt(curl, CURLOPT_URL, url);
        // 设置我们的回调函数来处理响应数据
        struct MemoryStruct chunk;
        chunk.memory = malloc(1);  // will be grown by realloc
        chunk.size = 0;    // no data at this point
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
        // 执行请求
        res = curl_easy_perform(curl);
        // 检查是否有错误发生
        if(res != CURLE_OK) {
            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        } else {
            // 解析 JSON 数据
            cJSON *json_root = cJSON_Parse(chunk.memory);
            if (json_root == NULL) {
                const char *error_ptr = cJSON_GetErrorPtr();
                if (error_ptr != NULL) {
                    fprintf(stderr, "Error before: %s\n", error_ptr);
                }
            } else {
                // 获取 "Global Quote" 对象
                cJSON *quote = cJSON_GetObjectItemCaseSensitive(json_root, "Global Quote");
                if (cJSON_IsObject(quote)) {
                    // 获取我们需要的字段
                    cJSON *price = cJSON_GetObjectItemCaseSensitive(quote, "05. price");
                    cJSON *change = cJSON_GetObjectItemCaseSensitive(quote, "09. change");
                    cJSON *change_percent = cJSON_GetObjectItemCaseSensitive(quote, "10. change percent");
                    cJSON *latest_trading_day = cJSON_GetObjectItemCaseSensitive(quote, "07. latest trading day");
                    if (cJSON_IsString(price) && cJSON_IsString(change) && cJSON_IsString(change_percent) && cJSON_IsString(latest_trading_day)) {
                        printf("\n--- Stock: %s ---\n", symbol);
                        printf("Latest Price: $%s\n", price->valuestring);
                        printf("Change: %s\n", change->valuestring);
                        printf("Change Percent: %s\n", change_percent->valuestring);
                        printf("As of: %s\n", latest_trading_day->valuestring);
                        printf("---------------------\n");
                    } else {
                        fprintf(stderr, "Error: Could not find price data in JSON response.\n");
                        // 打印原始 JSON 以便调试
                        // printf("Raw JSON: %s\n", chunk.memory);
                    }
                } else {
                    fprintf(stderr, "Error: 'Global Quote' object not found in JSON response.\n");
                    // 检查是否是 API 错误信息
                    cJSON *error_info = cJSON_GetObjectItemCaseSensitive(json_root, "Information");
                    if (cJSON_IsString(error_info)) {
                        fprintf(stderr, "API Error: %s\n", error_info->valuestring);
                    }
                }
                // 释放 JSON 对象
                cJSON_Delete(json_root);
            }
            // 释放内存
            free(chunk.memory);
        }
        // 清理 easy 会话
        curl_easy_cleanup(curl);
    }
    // 清理 libcurl 全局变量
    curl_global_cleanup();
}
int main(int argc, char *argv[]) {
    // 1. 配置你的 API 密钥和股票代码
    const char *API_KEY = "YOUR_API_KEY_HERE"; // <--- 在这里替换成你自己的 API 密钥
    const char *STOCK_SYMBOL = "IBM";           // 你想查询的股票代码,AAPL, MSFT, TSLA
    // 检查 API 密钥是否已设置
    if (strcmp(API_KEY, "YOUR_API_KEY_HERE") == 0) {
        fprintf(stderr, "Error: Please set your API_KEY in the source code (main.c).\n");
        return 1;
    }
    printf("Starting real-time stock price monitor for %s...\n", STOCK_SYMBOL);
    printf("Press Ctrl+C to stop.\n");
    // 2. 进入无限循环,定期获取数据
    while (1) {
        fetch_and_parse_stock(API_KEY, STOCK_SYMBOL);
        // 等待 10 秒
        printf("Fetching again in 10 seconds...\n");
        sleep(10);
    }
    return 0;
}

第 4 步:创建 Makefile (Makefile)

使用 Makefile 可以简化编译过程,确保所有库都正确链接。

# 定义编译器和编译选项
CC = gcc
CFLAGS = -Wall -Wextra -std=c99 -g
# 定义链接的库
LIBS = -lcurl -lcjson
# 目标文件
TARGET = stock_monitor
# 源文件
SOURCES = main.c
# 默认目标
all: $(TARGET)
# 编译规则
$(TARGET): $(SOURCES)
    $(CC) $(CFLAGS) -o $(TARGET) $(SOURCES) $(LIBS)
# 清理编译生成的文件
clean:
    rm -f $(TARGET)
# 假性目标,防止文件名冲突
.PHONY: all clean

第 5 步:编译和运行

  1. 修改 main.c:将 YOUR_API_KEY_HERE 替换成你从 Alpha Vantage 获取的真实 API 密钥。
  2. 编译:在终端中,进入项目目录,运行 make 命令。
    cd stock_price_monitor
    make

    如果一切顺利,它会编译并生成一个名为 stock_monitor 的可执行文件。

  3. 运行
    ./stock_monitor

你应该会看到类似下面的输出,并且它会每 10 秒自动刷新一次:

Starting real-time stock monitor for IBM...
Press Ctrl+C to stop.
--- Stock: IBM ---
Latest Price: $178.3400
Change: +0.8200
Change Percent: +0.4614%
As of: 2025-10-27
---------------------
Fetching again in 10 seconds...
--- Stock: IBM ---
Latest Price: $178.5100
Change: +0.9900
Change Percent: +0.5567%
As of: 2025-10-27
---------------------
Fetching again in 10 seconds...
...

Ctrl+C 可以停止程序。


进阶与扩展

这个项目是一个很好的起点,你可以基于它进行扩展:

  1. 命令行参数:使用 getopt 库让用户在运行时指定股票代码,而不是在代码中硬编码。

    ./stock_monitor -s AAPL
  2. 多股票监控:修改程序,使其可以同时监控多个股票,并将信息清晰地排列显示。

  3. 图形化界面 (GUI):如果你想做一个有界面的应用,可以考虑使用 GTK、Qt 或 SDL 等库来创建窗口和控件,将数据显示在 GUI 中,而不是终端。

  4. 数据持久化:将获取到的股价数据保存到文件(如 CSV)中,以便后续进行数据分析或绘制图表。

  5. 错误处理和重试机制:当 API 请求失败或达到调用限制时,程序可以等待更长时间或打印更友好的错误信息,而不是直接崩溃。

这个 C 语言实现展示了如何将底层系统调用与强大的第三方库结合起来,解决现实世界的问题。

文章版权及转载声明

作者:咔咔本文地址:https://www.jits.cn/content/31668.html发布于 04-03
文章转载或复制请以超链接形式并注明出处杰思科技・AI 股讯

阅读
分享

发表评论

快捷回复:

评论列表 (暂无评论,1人围观)参与讨论

还没有评论,来说两句吧...