【问题标题】:Taking into account \r\n考虑到\r\n
【发布时间】:2013-11-25 20:25:52
【问题描述】:

我正在尝试解决关于 spoj 的问题。显然,根据 cmets,输入行以 \r\n 结尾。我从以前的问题中对\r\n 的了解是它是一个Windows 的东西。我想知道的是如何考虑它。目前我在 C++ 中使用getline(cin,str)。我该怎么做才能考虑到\r\n.

【问题讨论】:

  • 您希望如何“考虑到它们”?
  • @mbratch 就像如何摆脱它并将行存储在字符串对象中

标签: c++ newline


【解决方案1】:

当您使用std::getline(std::cin, str) 时,'\n' 已被处理:std::getline() 将读取字符,直到找到'\n' 并将这些字符插入str。但是,它不会插入'\n'

因此,您可能会在字符串末尾遇到'\r'。如果您在 Windows 上,您只需以文本模式打开文件,流也会提取它们。如果这不是要走的路,您可以确定您的 str 是否以 '\r' 结尾并将其删除:

if (!str.empty() && str[str.size() - 1] == '\r') {
    str.erase(str.end() - 1);
}

如果你想删除所有回车(理论上可能有一些嵌入在字符串中),你可以使用

str.erase(std::remove(str.begin(), str.end(), '\r'), str.end());

最后,如果您不想遇到回车,您可以创建一个过滤流缓冲区,它只删除所有'\r'(或仅删除"\r\n" 序列中的那些)。下面是一个简单的过滤流缓冲区如何实现的简单示例:

#include <algorithm>
#include <iostream>
#include <streambuf>
#include <string>

class crfilter
    : std::streambuf
{
    std::istream*   stream;
    std::streambuf* sbuf;
    char buffer[8];
    int underflow() {
        std::streamsize n;
        while (this->gptr() == this->egptr()
            && (n = this->sbuf->sgetn(buffer, 8))) {
            char* end = std::remove(buffer, buffer + n, '\r');
            this->setg(buffer, buffer, end);
        }
        return this->gptr() == this->egptr()
            ? std::char_traits<char>::eof()
            : std::char_traits<char>::to_int_type(*this->gptr());
    }
public:
    crfilter(std::istream& in): stream(&in), sbuf(in.rdbuf(this)) {}
    ~crfilter() { stream->rdbuf(this->sbuf); }
};

int main()
{
    crfilter filter(std::cin);
    std::string str;
    while (std::getline(std::cin, str)) {
        std::cout << "str='" << str << "'\n";
    }
}

【讨论】:

    【解决方案2】:

    它们是回车/换行符,告诉您该行的结尾和下一行的开头。

    【讨论】:

    • 我很确定 OP 已经知道这一点。我认为他的问题更多地与如何在读取/写入文件时将它们剥离/添加回来有关。
    猜你喜欢
    • 1970-01-01
    • 2019-05-22
    • 2021-08-15
    • 1970-01-01
    • 2018-09-28
    • 1970-01-01
    • 2013-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多