C语言如何不修改结构体定义将格式化字符串解析存入结构体
问题原因
- 野指针访问:结构体中的
title、artist是未初始化的char*类型指针,没有指向合法的可写内存空间。sscanf的%s格式符需要向传入的地址写入解析到的字符串内容,直接传入野指针会触发非法内存访问,也就是你遇到的段错误。 - 格式串匹配错误:
%s默认会读取到空白符才停止,不会把逗号当做分隔符,哪怕指针合法,也会把整个"t,a,1990"全部写入第一个字段,无法实现按逗号拆分的需求。
解决方案
在不修改结构体定义的前提下,先给两个字符串指针分配足够的可写内存,同时调整sscanf的格式串为%[^,],匹配到逗号停止即可。
修正后代码如下:
#include <stdio.h> #include <stdlib.h> typedef struct { char* title; char* artist; int year; } song; int main(void) { song s; char str[]= "t,a,1990"; // 先给两个字符串成员分配足够的可写内存,这里按单个字段最长100字符为例 s.title = malloc(100); s.artist = malloc(100); // 严谨场景下需要判断malloc返回是否为NULL,处理内存分配失败的异常 if (!s.title || !s.artist) { perror("malloc failed"); return 1; } // 格式串%[^,]表示读取所有非逗号的字符,直到遇到逗号为止 sscanf(str, "%[^,],%[^,],%d", s.title, s.artist, &s.year); printf("title = %s, artist = %s, year= %d\n", s.title, s.artist, s.year); // 动态分配的内存使用完后需要释放,避免内存泄漏 free(s.title); free(s.artist); return 0; }
如果字段长度不确定,也可以先预扫描字符串计算每个字段的长度,再动态申请刚好大小的内存,避免空间浪费。如果仅在当前函数内使用结构体,也可以先定义栈字符数组存储解析结果,再把数组地址赋值给结构体的指针成员。
内容的提问来源于stack exchange,提问作者KiesM
相关产品推荐
相关产品推荐

