我一直在尝试使用sscanf
从输入文本中提取小时,秒和分钟。执行sscanf
函数后,只有保存秒的s
变量具有正确的值。其中包含小时和分钟的h
和m
仅包含零。请在下面建议更改我的代码。
char text[20];
if (fgets(text, sizeof text, stdin)!= NULL){
char* newline = strchr(text, '\n');
if (newline != NULL){
*newline = '\0';
}
}
uint8_t s = 0;
uint8_t m = 0;
uint8_t h = 0;
sscanf(text, "%02i:%02i:%02i",&h,&m,&s);
请注意,在调试器中,text具有正确的值。
答案 0 :(得分:3)
这个程序:
#include <stdio.h>
int main(void)
{
const char hhmmss[] = "10:32:54";
int hh, mm, ss;
if (sscanf(hhmmss, "%i:%i:%i", &hh, &mm, &ss) != 3)
printf("Failed to scan 3 values from '%s'\n", hhmmss);
else
printf("From <<%s>> hh = %d, mm = %d, ss = %d\n", hhmmss, hh, mm, ss);
return 0;
}
给出了这个输出:
From <<10:32:54>> hh = 10, mm = 32, ss = 54
%02i
转换也应该有效,但数字有些多余。
修正后的问题显示变量的类型为uint8_t
,在这种情况下,您必须使用<inttypes.h>
中的正确转换说明符:
#include <stdio.h>
#include <inttypes.h>
int main(void)
{
const char hhmmss[] = "10:32:54";
uint8_t s;
uint8_t m;
uint8_t h;
if (sscanf(hhmmss, "%02" SCNi8 ":%02" SCNi8 ":%02" SCNi8, &h, &m, &s) != 3)
printf("Failed to scan 3 values from '%s'\n", hhmmss);
else
printf("From <<%s>> h = %d, m = %d, s = %d\n", hhmmss, h, m, s);
return 0;
}
这产生与以前相同的输出。对于任何scanf()
系列函数,格式转换说明符与传递给函数的指针类型相匹配至关重要。你可以在printf()
中摆脱相当多的不匹配 - 当然是比较 - 因为默认的整数(特别是)促销,但scanf()
的宽容度要低得多。
答案 1 :(得分:2)
你应该从不使用scanf
或fscanf
或sscanf
来解析来自文件句柄或字符串的输入,除非可能是已知的抛弃了明天的代码。它们太容易出错并且难以控制。有关scanf
的各种问题的详尽摘要,我建议this series of articles。一些亮点:
getchar
。scanf
会遇到gets
的所有缓冲区溢出问题。scanf
的解析容易出错且难以使用。请改用strtoul
和strtod
。怎么办?
gets
更好的内容读取您自己的输入,即没有缓冲区溢出问题。不要试图将字节用于解释它们。strcspn
,strspn
,stroul
和strtod
以及一些自定义代码来扫描输入。有时候这也是拖累,但到那时你通常会构建某种输入语言,无论如何都需要更多的通用技术。