我正在为学校编写C ++代码,我只能使用std库,所以没有提升。我需要解析像“14:30”之类的字符串并将其解析为:
unsigned char hour;
unsigned char min;
我们将字符串作为c ++字符串,因此没有直接指针。我尝试了这段代码的所有变体:
sscanf(hour.c_str(), "%hhd[:]%hhd", &hours, &mins);
但我一直收到错误的数据。我做错了什么。
答案 0 :(得分:2)
正如其他人提到的那样,您必须使用指定的%d
格式(或%u
)。至于替代方法,我不是“因为C ++具有必须使用的功能XX”的忠实粉丝,并且经常使用C级功能。虽然我从不使用scanf()
- 就像它有自己的问题一样。话虽这么说,我将使用strtol()
解析您的字符串并进行错误检查:
#include <cstdio>
#include <cstdlib>
int main()
{
unsigned char hour;
unsigned char min;
const char data[] = "12:30";
char *ep;
hour = (unsigned char)strtol(data, &ep, 10);
if (!ep || *ep != ':') {
fprintf(stderr, "cannot parse hour: '%s' - wrong format\n", data);
return EXIT_FAILURE;
}
min = (unsigned char)strtol(ep+1, &ep, 10);
if (!ep || *ep != '\0') {
fprintf(stderr, "cannot parse minutes: '%s' - wrong format\n", data);
return EXIT_FAILURE;
}
printf("Hours: %u, Minutes: %u\n", hour, min);
}
希望它有所帮助。
答案 1 :(得分:2)
您的问题当然是您正在使用sscanf
。然后
你会在几小时和几分钟内使用一些非常特殊的类型
int
。因为你正在解析一个正好5个字符的字符串,所以
最简单的解决方案就是确保所有角色都合法
在该位置,使用isdigit
表示字符0,1,3和4,以及
与角色2的':'
相比。一旦你完成了它,它就是微不足道的
从字符串创建std::istringstream
,并输入到
int
,char
(之后你会忽略)和第二个int
。如果
你希望在输入中更灵活,例如允许事物
像"9:45"
一样,你可以跳过初始检查,只需输入
进入int
,char
和int
,然后检查char
是否包含':'
(并且两个int
在范围内)。
至于你的sscanf
失败的原因:你要求它匹配一些东西
比如"12[:]34"
,不你给它的是什么。我不确定
您是否尝试使用"%hhd:%hhd"
,或者出于某种原因使用[
真的想要一个角色类,在这种情况下,你必须使用"%hhd%*[:]%hhd"
转换说明符,然后忽略输入:%d
。
(这将允许接受多个字符作为分隔符,
但除此之外,我没有看到优势。另外,技术上至少,
使用unsigned
然后传递%hhd
整数类型的地址
不受支持,signed char
必须为{{1}}。在实践中,
但是,我认为你不会遇到任何问题
非负输入值小于128。)
答案 2 :(得分:1)
正如izomorphius sscanf
所提到的,变体不是C ++,它们是C.C ++方式是使用流。以下作品(它不是非常灵活,但应该给你一个想法)
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main(int argc, char* argv[])
{
string str = "14:30";
stringstream sstrm;
int hour,min;
sstrm << str;
sstrm >> hour;
sstrm.get(); // get colon
sstrm >> min;
cout << hour << endl;
cout << min << endl;
return 0;
}
您还可以使用getline
将所有内容放到冒号上。
答案 3 :(得分:1)
我会这样做
unsigned tmp_hour, tmp_mins;
unsigned char hour, mins;
sscanf(hour.c_str(), "%u:%u", &tmp_hours, &tmp_mins);
hour = tmp_hours;
mins = tmp_mins;
减少使用晦涩的scanf
选项。我也会添加一些错误检查。
答案 4 :(得分:0)
我的理解是h
中的%hhd
不是有效的格式说明符。十进制整数的正确说明符是%d
。
正如R.Martinho Fernandes在评论中所说,%d:%d
将匹配由冒号(':')分隔的两个数字。
你想要不同的东西吗?
您可以随时读取整个文本字符串并以任何方式解析它。
答案 5 :(得分:0)
sscanf
的 %hhd:%hhd
似乎完全正常:
std::string time("14:30");
unsigned char hour, min;
sscanf(time.c_str(), "%hhd:%hhd", &hour, &min);
请注意,hh
长度修饰符只是允许将值存储在unsigned char中。
但是,sscanf
来自C标准库,有更好的C ++方法可以做到这一点。 C ++ 11方法是使用stoi
:
std::string time("14:30");
unsigned char hour = std::stoi(time);
unsigned char min = std::stoi(time.substr(3));
在C ++ 03中,我们可以使用stringstream
,但如果您真的想要char
,那就有点痛苦了:
std::stringstream stream("14:30");
unsigned int hour, min;
stream >> hour;
stream.ignore();
stream >> min;