C语言中如何用单个sscanf函数读取文本文件所有数字
解决只用sscanf读取文本中所有数字的问题
我来帮你搞定这个问题!你遇到的核心问题是%*[^0-9]这个格式符的特性:当当前指针指向数字时,%*[^0-9]会试图匹配非数字字符,但找不到任何匹配项,导致sscanf直接返回0,触发你原来代码里的break,所以行首的数字就被漏掉了。
要解决这个问题,我们不需要依赖isdigit,只需要调整sscanf的调用逻辑:当跳过非数字的尝试失败时,直接尝试读取当前位置的数字,如果还是失败,就跳过当前的非数字字符继续循环。这样就能覆盖“行首是数字”和“行首是非数字”两种情况。
修改后的代码
int test(FILE *file, FILE *file2){ int l = 0; int nc = 0; char buffer[1000]; char *poi = NULL; fprintf(file2, "\n"); while(fgets(buffer, 1000, file) != NULL){ poi = buffer; while(*poi){ int ret; // 先尝试跳过所有非数字,再读取数字 ret = sscanf(poi, "%*[^0-9]%d%n", &zahl[l].number, &nc); if(ret == 1){ poi += nc; fprintf(file2, "%d ", zahl[l].number); l++; } else { // 跳过非数字失败,尝试直接读取当前位置的数字 ret = sscanf(poi, "%d%n", &zahl[l].number, &nc); if(ret == 1){ poi += nc; fprintf(file2, "%d ", zahl[l].number); l++; } else { // 当前既不是数字,后面也没有数字,跳过当前字符 poi++; } } } fprintf(file2, "\n"); } return 0; }
逻辑解释
- 第一次sscanf调用:
%*[^0-9]%d%n会先跳过所有非数字字符,然后读取一个整数,同时记录读取的字符数到nc。如果成功(返回1),就移动指针并处理数字。 - 如果第一次调用失败:说明当前指针指向的是数字(
%*[^0-9]匹配不到非数字),或者后面没有数字了。这时候我们直接尝试用%d%n读取当前位置的数字:- 如果成功,说明当前是数字,处理后移动指针。
- 如果还是失败,说明当前是非数字且后面没有数字,直接移动指针到下一个字符继续循环。
验证示例文本
对于你给出的示例文本:
text 2025 text text 25 text text text 1h text 26 text text text text 4,5h. text text text text 19h
修改后的代码会输出:
2025 25 1 26 4 5 19
完全符合你的期望。
内容的提问来源于stack exchange,提问作者keita063
相关产品推荐
相关产品推荐

