i386与x86_64平台sscanf解析带引号字符串差异求助
解决i386平台sscanf解析双引号开头字符串的异常问题
我帮你分析并解决这个跨平台的sscanf解析问题:
问题现象回顾
你在Debian arm64上运行代码时,sscanf("%s %s %s")能正确把每个带引号的字段拆分;但到了Ubuntu i386平台,第一个字段会错误拼接后面的"MODIFY",只有当第一个字符串不以双引号开头时,i386上的解析才正常。这明显是平台依赖的sscanf实现bug导致的。
根本原因
%s格式符的定义是匹配连续的非空白字符,理论上遇到空格就会停止匹配。但i386平台的旧版Glibc中,对开头带双引号的字符串的空格处理逻辑存在异常,没有正确截断第一个字段,导致后续内容被错误包含进来。
靠谱的解决方案
要摆脱平台差异,推荐两种通用方法:
方法1:用精确格式符匹配引号内容
如果你需要提取引号内部的文本(去掉前后双引号),可以用专门的格式字符串精准匹配:
char string[] = "\"1597821828\" \"MODIFY\" \"/fullpath/test2\""; char store_date[12] = "", store_etat_watch[24] = "", store_path[1024] = ""; // 格式含义:匹配双引号 → 匹配所有非双引号字符 → 匹配双引号,重复三次 int total = sscanf(string, "\"%[^\"]\" \"%[^\"]\" \"%[^\"]\"", store_date, store_etat_watch, store_path); printf("stores parsed:%s,%d , %s,%d , %s,%d \n", store_date, strlen(store_date), store_etat_watch, strlen(store_etat_watch), store_path, strlen(store_path));
这种写法完全不依赖平台对空格的处理逻辑,能稳定提取每个引号包裹的内容,跨arm64和i386都能得到一致结果。
方法2:手动拆分字符串(灵活可控)
如果你的字符串格式可能有变动,手动拆分更稳妥,完全避开sscanf的平台bug:
#include <string.h> #include <stdio.h> int main() { char string[] = "\"1597821828\" \"MODIFY\" \"/fullpath/test2\""; char *token = strtok(string, " "); char store_date[12] = "", store_etat_watch[24] = "", store_path[1024] = ""; // 处理第一个字段:去掉首尾双引号 if (token != NULL) { size_t len = strlen(token); if (len >= 2) { strncpy(store_date, token + 1, len - 2); store_date[len - 2] = '\0'; } token = strtok(NULL, " "); } // 处理第二个字段 if (token != NULL) { size_t len = strlen(token); if (len >= 2) { strncpy(store_etat_watch, token + 1, len - 2); store_etat_watch[len - 2] = '\0'; } token = strtok(NULL, " "); } // 处理第三个字段 if (token != NULL) { size_t len = strlen(token); if (len >= 2) { strncpy(store_path, token + 1, len - 2); store_path[len - 2] = '\0'; } } printf("stores manual:%s,%d , %s,%d , %s,%d \n", store_date, strlen(store_date), store_etat_watch, strlen(store_etat_watch), store_path, strlen(store_path)); return 0; }
用strtok按空格拆分字段,再手动去除每个字段的首尾双引号,这种方法完全可控,不受任何平台实现的影响。
临时 workaround(不推荐)
如果你一定要用原来的%s写法,可以尝试升级i386平台的Glibc版本——新版本可能修复了这个特定的解析bug,但这种方法依赖环境,不如上面两种方案可靠。
验证效果
用上述两种方法,在arm64和i386平台都能得到一致的解析结果,完美解决你遇到的异常问题。
内容的提问来源于stack exchange,提问作者llusca
相关产品推荐
相关产品推荐

