"Blocking" 下一个 cout
"Blocking" next cout
我想知道是否有办法 "block" cout 输出接下来的几个字符或下一个命令。
我有一个功能,我不能在开始时用打印更改,我想覆盖下一个打印。
void overridePrint(){
std::cout << "Replaced header" << std::endl;
print(); //prints another header
}
void print(){
std::cout << "Normal header" << std::endl;
std::cout << "other prints";
//...
}
我知道有一种方法可以暂时禁用输出,但由于我无法在第一次打印后修改打印功能以启用它,所以我真的不知道该怎么做。可以只复制整个函数,但这并不好。
我很好奇,并受此代码审查 https://codereview.stackexchange.com/q/104428/38143 post 启发写了这个概念证明。为此使用 std::codecvt
可能是愚蠢的 hack,代码可能包含错误,因此使用风险自负:
#include <locale>
#include <algorithm>
#include <iostream>
#include <iomanip>
class swallow_line_facet : public std::codecvt<char, char, std::mbstate_t> {
public:
swallow_line_facet(std::size_t ref = 0)
: std::codecvt<char, char, std::mbstate_t>(ref) {}
protected:
result do_out(
state_type &,
const intern_type* from,
const intern_type* from_end,
const intern_type*& from_next,
extern_type* to,
extern_type* to_end,
extern_type*& to_next) const override
{
if (is_done)
return std::codecvt_base::noconv;
for (; (from < from_end) && (to < to_end); from++) {
char c = *from;
if (is_done)
*to++ = c;
if (c == '\n')
is_done = true;
}
from_next = from;
to_next = to;
return from == from_end
? std::codecvt_base::ok
: std::codecvt_base::partial;
}
virtual bool do_always_noconv() const noexcept override {
return is_done;
}
private:
mutable bool is_done = false;
};
std::ostream& swallow_line(std::ostream& out)
{
out.imbue(std::locale(out.getloc(), new swallow_line_facet));
return out;
}
演示
int main() {
/// This probably has to be called once for every program:
//
std::ios_base::sync_with_stdio(false);
std::cout << "first line" << '\n' << swallow_line;
std::cout << "second line" << '\n';
std::cout << "third line" << '\n' << swallow_line;
std::cout << "fourth line" << '\n';
std::cout << "fifth line" << '\n';
}
输出:
first line
third line
fifth line
您的情况下的用法:
void overridePrint(){
std::cout << "Replaced header" << std::endl;
std::cout << swallow_line;
print();
}
int main() {
/// don't forget this
std::ios_base::sync_with_stdio(false);
// ...
}
我想知道是否有办法 "block" cout 输出接下来的几个字符或下一个命令。 我有一个功能,我不能在开始时用打印更改,我想覆盖下一个打印。
void overridePrint(){
std::cout << "Replaced header" << std::endl;
print(); //prints another header
}
void print(){
std::cout << "Normal header" << std::endl;
std::cout << "other prints";
//...
}
我知道有一种方法可以暂时禁用输出,但由于我无法在第一次打印后修改打印功能以启用它,所以我真的不知道该怎么做。可以只复制整个函数,但这并不好。
我很好奇,并受此代码审查 https://codereview.stackexchange.com/q/104428/38143 post 启发写了这个概念证明。为此使用 std::codecvt
可能是愚蠢的 hack,代码可能包含错误,因此使用风险自负:
#include <locale>
#include <algorithm>
#include <iostream>
#include <iomanip>
class swallow_line_facet : public std::codecvt<char, char, std::mbstate_t> {
public:
swallow_line_facet(std::size_t ref = 0)
: std::codecvt<char, char, std::mbstate_t>(ref) {}
protected:
result do_out(
state_type &,
const intern_type* from,
const intern_type* from_end,
const intern_type*& from_next,
extern_type* to,
extern_type* to_end,
extern_type*& to_next) const override
{
if (is_done)
return std::codecvt_base::noconv;
for (; (from < from_end) && (to < to_end); from++) {
char c = *from;
if (is_done)
*to++ = c;
if (c == '\n')
is_done = true;
}
from_next = from;
to_next = to;
return from == from_end
? std::codecvt_base::ok
: std::codecvt_base::partial;
}
virtual bool do_always_noconv() const noexcept override {
return is_done;
}
private:
mutable bool is_done = false;
};
std::ostream& swallow_line(std::ostream& out)
{
out.imbue(std::locale(out.getloc(), new swallow_line_facet));
return out;
}
演示
int main() {
/// This probably has to be called once for every program:
//
std::ios_base::sync_with_stdio(false);
std::cout << "first line" << '\n' << swallow_line;
std::cout << "second line" << '\n';
std::cout << "third line" << '\n' << swallow_line;
std::cout << "fourth line" << '\n';
std::cout << "fifth line" << '\n';
}
输出:
first line
third line
fifth line
您的情况下的用法:
void overridePrint(){
std::cout << "Replaced header" << std::endl;
std::cout << swallow_line;
print();
}
int main() {
/// don't forget this
std::ios_base::sync_with_stdio(false);
// ...
}