C++ sscanf c++;将字符串拆分为整数有时不会';行不通

C++ sscanf c++;将字符串拆分为整数有时不会';行不通,c++,string,split,int,scanf,C++,String,Split,Int,Scanf,我正在编写一个程序,将日期字符串转换为三个独立的int变量:年、月、日 int m,d,y; sscanf("2011-03-08","%i %*[-] %i %*[-] %i",&y,&m,&d); cout << y<<" "<<m<<" "<<" "<<d<<std::endl; sscanf("2011-03-07","%i %*[-] %i %*[-] %i",&y,&a

我正在编写一个程序,将日期字符串转换为三个独立的int变量:年、月、日

int m,d,y;
sscanf("2011-03-08","%i %*[-] %i %*[-] %i",&y,&m,&d);
cout << y<<" "<<m<<" "<<" "<<d<<std::endl;
sscanf("2011-03-07","%i %*[-] %i %*[-] %i",&y,&m,&d);
cout << y<<" "<<m<<" "<<" "<<d;
int m,d,y;
sscanf(“2011-03-08”、%i%*[-]%i%*[-]%i”、&y、&m、&d);
看

i
匹配可选带符号整数;下一个指针必须是指向int的指针。如果整数以0x或0x开头,则在基数16中读取,如果整数以0开头,则在基数8中读取,否则在基数10中读取。仅使用与基相对应的字符

08
将作为八进制整数扫描,因为它以
0
开头。但是
08
不是有效的八进制整数,而
07
是。如果您使用
%d
而不是
%i
,它将按预期工作

sscanf("2011-03-08","%d %*[-] %d %*[-] %d", &y, &m, &d);
甚至更简单

sscanf("2011-03-08","%d-%d-%d", &y, &m, &d);

根据你想对结果做什么,你也可以考虑

strtime-将时间的字符串表示形式转换为time tm结构


您的格式字符串错误。。。它应该是
%4d-%02d-%02d”


<检查> ScScF也不会有害,如果<代码> >(3!= sSCANF(…)){/***/} <代码> < /P> > P >问题是:<代码> %I/COD>将代码> 08 < /C>作为八进制整数,因此可能的解决方案可以使用<代码> %D< /代码>,<强>但< /强>,因为这是C++,您应该使用(<代码>包含< < /代码>)相反:

int y,m,d;
字符分隔符;
std::istringstream数据流(“2011-03-08”);
日期流>>y>>分隔符>>m>>分隔符>>d;

STD::我想可能是因为八进制,尝试使用%DU,你不应该用C和C++来这样混合。这些是不同的语言,因此在用C++1编程时避免编写C风格的代码。然而,问这个问题的人可能更喜欢使用std::istringstream而不是sscanf。@另一个测试同意,这将是下一步。但如果他必须维护一些现有代码,这可能不是一个选项。@另一个测试:流并不总是一个选项。如果在编译时格式未知怎么办?有这么多的日期格式。。。此外,对于更复杂的解析任务,流不能支持
sscanf
,实际上,它实现了一种小型解析器。不过,正则表达式可能更像它;尤其是现在它们已经标准化了。那绝对是真的。虽然只有在运行时才知道格式中存在细微的差异(例如,如果我们使用了不同的分隔符),但这根本不应该是一个问题。如果您正在处理更复杂的语言,您可能会选择更强大的解析方法。正如你所说,正则表达式可能也是一个好主意。你每次都忘了验证
分隔符是否真的是
'-'
,而
sscanf
隐含地为你做了验证,所以它并不完全等价。@MatthieuM:这一点很好,尽管我不是说它完全等价于
sscanf
。我只是想指出还有其他可能的解决办法。
struct tm t;
strptime("2011-03-08, "%Y-%m-%d", &t);
int y,m,d;
char delimiter;

std::istringstream dateStream("2011-03-08");
dateStream >> y >> delimiter >> m >> delimiter >> d;

std::cout << y << " " << m << " " << d;