如何读取结构体中的值?使用fread触发段错误问题排查
解决fread读取结构体引发的Segmentation Fault问题
错误原因分析
- 结构体
credentials的成员都是char*指针,但你仅给to_number分配了内存(还写错了变量名),其他三个指针均为未初始化的野指针,fscanf直接写入这些野指针指向的地址会触发段错误。 - 错误使用
fread:你的配置文件是文本格式,但fread用于读取二进制数据,用它读文本文件会把内容当作二进制结构体数据直接写入c1,导致指针成员被乱赋值,进一步引发错误。 - 未检查命令行参数:直接使用
argv[1]和argv[2],若运行程序时未传入足够参数,会访问非法内存导致段错误。 - 存在未使用的变量(
main里的input)和未关闭的文件句柄,代码逻辑混乱。
修正后的代码
#include <string.h> #include <stdio.h> #include <stdlib.h> int twilio_send_functionapi(char *channel, char *status); // 函数声明 struct credentials { char *account_sid; char *auth_token; char *from_number; char *to_number; } c1; int main(int argc, char *argv[]) { // 检查命令行参数是否足够 if (argc < 3) { printf("请传入channel和status参数\n"); return -1; } FILE *fp; fp = fopen("data.config", "r"); if (fp == NULL) { printf("打开文件失败\n"); return -1; } // 为结构体所有指针成员分配内存(每个成员最多存100字符) c1.account_sid = malloc(sizeof(char) * 100); c1.auth_token = malloc(sizeof(char) * 100); c1.from_number = malloc(sizeof(char) * 100); c1.to_number = malloc(sizeof(char) * 100); // 检查内存分配是否成功 if (!c1.account_sid || !c1.auth_token || !c1.from_number || !c1.to_number) { printf("内存分配失败\n"); fclose(fp); // 释放已分配的内存 if (c1.account_sid) free(c1.account_sid); if (c1.auth_token) free(c1.auth_token); if (c1.from_number) free(c1.from_number); if (c1.to_number) free(c1.to_number); return -1; } // 逐行读取配置文件,跳过键名,只读取值 fscanf(fp, "account_sid : %s", c1.account_sid); fscanf(fp, "auth_token : %s", c1.auth_token); fscanf(fp, "from_number : %s", c1.from_number); fscanf(fp, "to_number : %s", c1.to_number); char *channel = argv[1]; char *status = argv[2]; twilio_send_functionapi(channel, status); // 函数调用 // 释放内存 free(c1.account_sid); free(c1.auth_token); free(c1.from_number); free(c1.to_number); // 关闭文件 fclose(fp); return 0; }
如何读取结构体中的值
结构体的成员可以直接通过.运算符访问(针对结构体变量),或者->运算符(针对结构体指针)。示例:
// 直接访问结构体变量的成员 printf("Account SID: %s\n", c1.account_sid); printf("Auth Token: %s\n", c1.auth_token); printf("From Number: %s\n", c1.from_number); printf("To Number: %s\n", c1.to_number);
如果是结构体指针(如struct credentials *p = &c1;),则用:
printf("Account SID: %s\n", p->account_sid);
内容的提问来源于stack exchange,提问作者nima
相关产品推荐
相关产品推荐

