提问人:nameses 提问时间:6/8/2022 更新时间:6/8/2022 访问量:352
编写自定义输入操纵器
Writing a custom input manipulator
问:
我需要制作一个自定义 istream 操纵器,该操作器从输入中读取 5 个字符,然后从输入中跳过 5 个字符,并执行到字符串末尾。例:
string line;
cin >> skipchar >> line;
这是我做的,但由于某种原因它不起作用。另外,如果我不使用,那就更好了<sstream>
struct membuf : streambuf
{
membuf(char* begin, char* end) {
this->setg(begin, begin, end);
}
};
istream& skipchar(istream& stream)
{
string temp;
getline(stream, temp);
char *str = new char[temp.size() + 1];
strcpy(str, temp.c_str());//get string and convert to char*
char* res = new char[strlen(str)];
for (int i=0,j=0;i<strlen(str);i++)
if ((i / 5) % 2 == 0) //get first 5, then 5 skip, etc
res[j++] = str[i];
membuf b(res, res + strlen(res)); //copy str to buffer
stream.rdbuf(&b);
return stream;
}
int main()
{
string str;
cout << "enter smth:\n";
cin >> skipchar >> str;
cout << "entered string: " << str;
return 0;
}
答:
您没有显示您的意见,但我认为在这种情况下使用不适合。 意思是读一个字,而不是一整行。getline()
operator>>
无论如何,您都会泄漏您分配的两个数组。使用完它们后,您需要使用它们。对于数组(仅供参考,您实际上并不需要,因为您可以将字符串中的字符直接复制到其中),您可以在退出之前使用它。但是对于 ,当 本身不再被使用时,它必须保留该指针和它。char[]
delete[]
str
temp
res
delete[]
res
membuf
delete[]
membuf
但是,更重要的是,你使用您正在将其创建为 的局部变量,因此它将在退出时被销毁,留下指向无效对象的悬空指针。分配给 的指针必须在分配给 的整个持续时间内保持有效,这意味着使用 创建对象,然后调用方必须记住稍后手动操作它(这有点违背了使用 的目的)。但是,流操纵器实际上不应该首先更改所指向的内容,因为在后续读取操作完成后,没有一种好的方法可以恢复以前的操作(除非您定义另一个操纵器来处理它,即)。membuf
skipchar()
skipchar()
stream
streambuf*
stream
istream
membuf
new
delete
operator>>
rdbuf
stream
streambuf
cin >> skipchar >> str >> stopskipchar;
在这种情况下,我建议采取不同的方法。不要创建流操纵器,将 new 分配给 ,从而影响所有后续调用。取而代之的是,创建一个引用输出变量的操纵器,然后从 和 仅输出所需的内容(类似于 std::quoted 和 std
::get_time
等标准操纵器的工作方式),例如:streambuf
stream
operator>>
stream
struct skipchars
{
string &str;
};
istream& operator>>(istream& stream, skipchars output)
{
string temp;
if (stream >> temp) {
for (size_t i = 0; i < temp.size(); i += 10) {
output.str += temp.substr(i, 5);
}
}
return stream;
}
int main()
{
string str;
cout << "enter smth:\n";
cin >> skipchars{str};
cout << "entered string: " << str;
return 0;
}
或者:
struct skipcharsHelper
{
string &str;
};
istream& operator>>(istream& stream, skipcharsHelper output)
{
string temp;
if (stream >> temp) {
for (size_t i = 0; i < temp.size(); i += 10) {
output.str += temp.substr(i, 5);
}
}
return stream;
}
skipcharsHelper skipchars(string &str)
{
return skipcharsHelper{str};
}
int main()
{
string str;
cout << "enter smth:\n";
cin >> skipchars(str);
cout << "entered string: " << str;
return 0;
}
评论
cin >> skipchar >>行;”
- 对不起,但是没有安全的方法可以按照您想要的方式实现该语法(无论如何,我知道)。我建议的方法有什么问题?这是标准库实现此类操纵器的方式,那么为什么不能遵循相同的模式呢?
上一个:弃用的含义?
评论