如何在C语言中实现实时股价数据的获取与动态展示?
摘要:
我将为你提供一个完整、可运行的 C 语言项目,它能够:使用 libcurl 库从 Alpha Vantage 的免费 API 获取实时股票数据,使用 cJSON 库解析返回的 JS... 我将为你提供一个完整、可运行的 C 语言项目,它能够:
- 使用
libcurl库从 Alpha Vantage 的免费 API 获取实时股票数据。 - 使用
cJSON库解析返回的 JSON 格式数据。 - 将获取到的股价信息清晰地打印在控制台。
- 通过一个循环,每隔一段时间(10 秒)自动刷新数据,实现“实时”效果。
项目结构
你的项目文件可以这样组织:
stock_price_monitor/
├── main.c
├── Makefile
└── README.md
第 1 步:获取 API 密钥
你需要一个免费的股票数据 API,这里我们使用 Alpha Vantage,它提供免费的 API 调用额度。
- 访问 Alpha Vantage 官网 并注册一个免费账户。
- 注册后,你将获得一个 API 密钥(一串字符),
XXXXXXXXXXXXXXXX。
注意: 免费账户有调用频率限制(每分钟 5 次,每天 500 次),请勿滥用。
第 2 步:安装必要的库
你需要安装 libcurl 和 cJSON,如果你使用的是基于 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 步:编译和运行
- 修改
main.c:将YOUR_API_KEY_HERE替换成你从 Alpha Vantage 获取的真实 API 密钥。 - 编译:在终端中,进入项目目录,运行
make命令。cd stock_price_monitor make
如果一切顺利,它会编译并生成一个名为
stock_monitor的可执行文件。 - 运行:
./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 可以停止程序。
进阶与扩展
这个项目是一个很好的起点,你可以基于它进行扩展:
-
命令行参数:使用
getopt库让用户在运行时指定股票代码,而不是在代码中硬编码。./stock_monitor -s AAPL
-
多股票监控:修改程序,使其可以同时监控多个股票,并将信息清晰地排列显示。
-
图形化界面 (GUI):如果你想做一个有界面的应用,可以考虑使用 GTK、Qt 或 SDL 等库来创建窗口和控件,将数据显示在 GUI 中,而不是终端。
-
数据持久化:将获取到的股价数据保存到文件(如 CSV)中,以便后续进行数据分析或绘制图表。
-
错误处理和重试机制:当 API 请求失败或达到调用限制时,程序可以等待更长时间或打印更友好的错误信息,而不是直接崩溃。
这个 C 语言实现展示了如何将底层系统调用与强大的第三方库结合起来,解决现实世界的问题。
作者:咔咔本文地址:https://www.jits.cn/content/31668.html发布于 04-03
文章转载或复制请以超链接形式并注明出处杰思科技・AI 股讯
还没有评论,来说两句吧...