跳过预期的字符,如 scanf() 和 cin
Skipping expected characters like scanf() with cin
如何在C++中用cin
实现scanf("%d # %d",&a,&b);
效果?
您可以通过
将其提取为字符来跳过#
:
std::istringstream iss("10 # 20");
int main()
{
int a, b; char hash;
iss >> a >> hash >> b;
assert(a == 10 && b == 20);
}
您可以创建自己的流操纵器。这是相当容易的。
#include <ios>
#include <iostream>
using namespace std;
// skips the number of characters equal to the length of given text
// does not check whether the skipped characters are the same as it
struct skip
{
const char * text;
skip(const char * text) : text(text) {}
};
std::istream & operator >> (std::istream & stream, const skip & x)
{
ios_base::fmtflags f = stream.flags();
stream >> noskipws;
char c;
const char * text = x.text;
while (stream && *text++)
stream >> c;
stream.flags(f);
return stream;
}
int main()
{
int a, b;
cin >> a >> skip(" # ") >> b;
cout << a << ", " << b << endl;
return 0;
}
不幸的是
,istream
类内部没有模仿它的直接函数。您可以使用一些函数来操作流并获得正确的输入,但我不熟悉它们的工作原理,所以我无法告诉您如何工作。
关于我个人如何做到这一点,我最好的建议是使用 getline()
将输入放入字符串中,然后从那里进行一些检查以查看它是否与格式匹配。所以在你的例子中,我会抓住第一个子字符串直到第一个空格,确保它是一个有效的小数,检查以确保井号 ('#') 在正确的位置,然后抓住结束数字以确保它是有效的。如果这三个对象中的任何一个不正确,我会设置一些布尔变量来false
踢出或返回,或者指示输入无效且格式不正确。
伪代码:
...
getline(cin,myStr);
while(!formatCheck(myStr))
{
cout<<"Not valid format for input";
getline(cin,myStr);
}
...
bool formatCheck(string str)
{
string firstPart=str.subString(0,firstSpaceLocation);
string middle=str[firstSpaceLocation+1];
string lastPart=str.subString(firstSpaceLocation+3,end);
if(first part not a valid number || middle!="#" || last part not a valid number)
{
return false;
}
return true;
}
这是另一种方式。您可以通过区域设置中嵌入的std::ctype<char>
方面将#
分类为空格字符:
#include <iostream>
#include <sstream>
#include <vector>
namespace detail
{
enum options { add, remove };
class ctype : public std::ctype<char>
{
private:
static mask* get_table(const std::string& ws, options opt)
{
static std::vector<mask> table(classic_table(),
classic_table() + table_size);
for (char c : ws)
{
if (opt == add)
table[c] |= space;
else if (opt == remove)
table[c] &= ~space;
}
return &table[0];
}
public:
ctype(const std::string& ws, options opt)
: std::ctype<char>(get_table(ws, opt)) { }
};
}
class adjustws_impl
{
public:
adjustws_impl(const std::string& ws, detail::options opt) :
m_ws(ws),
m_opt(opt)
{ }
friend std::istream& operator>>(std::istream& is,
const adjustws_impl& manip)
{
is.imbue(std::locale(is.getloc(),
new detail::ctype(manip.m_ws, manip.m_opt)));
return is;
}
private:
std::string m_ws;
detail::options m_opt;
};
adjustws_impl setws(const std::string& ws)
{
return adjustws_impl(ws, detail::add);
}
adjustws_impl unsetws(const std::string& ws)
{
return adjustws_impl(ws, detail::remove);
}
int main()
{
std::istringstream iss("10 # 20");
int a, b;
iss >> setws("#");
iss >> a >> b;
iss >> unsetws("#");
std::cout << a << ' ' << b; // 10 20
}
您可以使用 std::istream::ignore 跳过#
或任何单个字符
std::istringstream sstr("1024 # 768");
int main()
{
int a, b;
sstr >> a;
sstr.ignore(256,'#'); // ignore until hash character
sstr >> b;
std::cout << "a: " << a << " b: " << b << std::endl;
}
相关文章:
- C++中的cin.ignore()函数不适用于整个流
- 在while循环中输入带有std::cin的字符串后,控制台会输出大量胡言乱语
- Problems with std::cin.fail()
- 由cin中的字符串中未捕获空白引起的分割错误
- 为什么 printf 在 C++ 中的执行速度比 cout 快?另外scanf比cin慢,为什么?
- 有没有办法中止 cin 或 scanf
- 将整数输入数组的方法比 scanf() 或 cin 更快?
- STD :: cin和Scanf()应用于字符串之间的区别
- 为什么 CIN / COUT 比 scanf/printf 慢
- 如何从文件中一次读取一个输入,类似于在c++中使用cin/scanf从控制台读取输入
- 执行时间以C++显示:cin/scanf/getchar_unlocked()
- 跳过预期的字符,如 scanf() 和 cin
- 从printf-scanf转换为cin-cout时出现问题
- 由于 istream 中的杂散 导致 get () 的结果不正确,但 scanf() 或 cin 则不然
- scanf(), std::cin 在多线程环境中的行为如何
- 为什么在这种情况下"printf scanf"比"cout cin"慢?
- c/c++scanf/cin从多行读取int
- 从scanf和cin获取变量
- c++,使用 cin 针对 scanf 输入的值
- 何时使用printf/scanf与cout/cin