如何使用cin>>模拟scanf("%*c")与scanf(":")的行为,无需手动校验字符
等效实现方案
模拟 scanf("%*c") 逻辑
直接调用cin.ignore()即可,该方法默认会消耗并丢弃输入流中的下一个任意字符,不会跳过空白符,和scanf("%*c")行为完全一致,不需要额外定义变量存储字符。
示例:
// 等价于 scanf("%*c"); cin.ignore();
模拟 scanf(":") 逻辑
scanf(":")的规则是仅当下一个字符是冒号时才消耗该字符,否则直接设置输入流fail位,不消耗任何字符。不需要额外定义变量校验的实现方式如下:
// 等价于 scanf(":"); if (cin.peek() == ':') { cin.ignore(); } else { cin.setstate(std::ios::failbit); }
如果需要复用这个逻辑,可以自定义一个通用的字符匹配操纵符,用法更简洁:
// 自定义操纵符定义 struct match_char { char target; explicit match_char(char c) : target(c) {} friend std::istream& operator>>(std::istream& is, const match_char& m) { if (is.peek() == m.target) { is.ignore(); } else { is.setstate(std::ios::failbit); } return is; } }; // 使用时直接按以下写法调用,和scanf的普通字符匹配用法对齐 cin >> match_char(':');
完整等效代码
#include <iostream> #include <ios> struct match_char { char target; explicit match_char(char c) : target(c) {} friend std::istream& operator>>(std::istream& is, const match_char& m) { if (is.peek() == m.target) { is.ignore(); } else { is.setstate(std::ios::failbit); } return is; } }; int main() { char ch; // 对应 scanf("%*c"); std::cin.ignore(); // 对应 scanf(":"); std::cin >> match_char(':'); // 原有逻辑 std::cin >> ch; return 0; }
注意事项
cin>>默认会自动跳过前置空白符,如果要完全对齐scanf的匹配逻辑(不跳过空白),可以在操作前关闭skipws标记:
cin.unsetf(std::ios::skipws); // 操作完成后如果需要恢复默认行为可以再执行:cin.setf(std::ios::skipws);
内容的提问来源于stack exchange,提问作者BenevolentDeity
相关产品推荐
相关产品推荐

