矢量的unsigned char迭代器不工作

时间:2014-01-27 17:06:01

标签: c++ vector stl iterator

我想在向量的末尾剪切CRLF,但我的代码不起作用(在while的第一个循环中 - 相等就是调用并返回false)。在调试模式“i”== 0并且“ptr”值==“0x002e4cfe”

string testS = "\r\n\r\n\r\n<-3 CRLF Testing trim new lines 3 CRLF->\r\n\r\n\r\n";
vector<uint8> _data; _data.clear();
_data.insert(_data.end(), testS.begin(), testS.end());
vector<uint8>::iterator i = _data.end();
uint32 bytesToCut = 0;

while(i != _data.begin()) {
    if(equal(i - 1, i, "\r\n")) {
        bytesToCut += 2;                
        --i; if(i == _data.begin()) return; else --i;
    } else {
        if(bytesToCut) _data.erase(_data.end() - bytesToCut, _data.end());
        return;
    }                    
}

非常感谢您的回答。但我需要带有迭代器的版本,因为我的代码是在解析分块的http传输数据时使用的,它被写入向量并且我需要func,它将获取指向向量的指针和迭代器定义向后移除CRLF的位置。我认为,我所有的问题显然都包含在迭代器中。

4 个答案:

答案 0 :(得分:0)

首先,矢量初始化是......非最佳的。你需要做的就是:

string testS = "\r\n\r\n\r\n<-3 CRLF Testing trim new lines 3 CRLF->\r\n\r\n\r\n";
vector<uint8> _data(testS.begin(), testS.end());

其次,如果你想删除\r\n字符,你可以在字符串中完成它:

testS.erase(std::remove_if(testS.begin(), testS.end(), [](char c)
{
    return c == '\r' || c == '\n';
}), testS.end());

如果您想在向量中执行此操作,则它是相同的基本过程:

_data.erase(std::remove_if(_data.begin(), _data.end(), [](uint8 ui)
{
    return ui == static_cast<uint8>('\r') || ui == static_cast<uint8>('\n');
}), _data.end());

您的问题可能是由于在循环中使用了无效的迭代器(有其他几个逻辑问题,但因为它不应该存在,我不会触及),它会逐个删除元素。

如果你想从字符串/向量的末尾删除项目,它会略有不同,但仍然是相同的基本模式:

int start = testS.find_first_not_of("\r\n", 0); // finds the first non-\r\n character in the string
int end = testS.find_first_of("\r\n", start); // find the first \r\n character after real characters
// assuming neither start nor end are equal to std::string::npos - this should be checked
testS.erase(testS.begin() + end, testS.end()); // erase the `\r\n`s at the end of the string.

或者(如果\r\n也可以在字符串的中间):

std::string::reverse_iterator rit = std::find_if_not(testS.rbegin(), testS.rend(), [](char c)
{
    return c == '\r' || c == '\n';
});
testS.erase(rit.base(), testS.end());

答案 1 :(得分:0)

相反,如果重新发明轮子,你可以用现有的STL算法:

std::string s;
s = s.substr(0, s.find_last_not_of(" \r\n"));

答案 2 :(得分:0)

如果您需要修剪'\r'&amp;从最后'\n'开始,简单substr即可:

std::string str = "\r\n\r\n\r\nSome string\r\n\r\n\r\n";

size_t newLength = str.length();
while (str[newLength - 1] == '\r' || str[newLength - 1] == '\n') newLength--;
str = str.substr(0, newLength);

std::cout << str;

不要吝啬小东西:)


删除所有'\r''\n'可能很简单,因为(C ++ 03):

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

int main() {
    std::string str = "\r\n\r\n\r\nSome string\r\n\r\n\r\n";
    str.erase(std::remove(str.begin(), str.end(), '\r'), str.end());
    str.erase(std::remove(str.begin(), str.end(), '\n'), str.end());
    std::cout << str;
}

或:

bool isUnwantedChar(char c) {
    return (c == '\r' || c == '\n');
}

int main() {
    std::string str = "\r\n\r\n\r\nSome string\r\n\r\n\r\n";
    str.erase(std::remove_if(str.begin(), str.end(), isUnwantedChar), str.end());
    std::cout << str;
}

答案 3 :(得分:0)

您的代码无效,至少是因为在算法std :: equal

中设置了不正确的范围
if(equal(i - 1, i, "\r\n")) {

在此表达式中,只比较迭代器i - 1指向的向量的一个元素和'\ r'。你必须写一些东西

if(equal(i - 2, i, "\r\n")) {

如果您需要从向量中删除“\ r \ n”对,那么我可以建议以下方法(我使用自己的变量名并包含测试输出):

std::string s = "\r\n\r\n\r\n<-3 CRLF Testing trim new lines 3 CRLF->\r\n\r\n\r\n";
std::vector<unsigned char> v( s.begin(), s.end() );

std::cout << v.size() << std::endl;

auto last = v.end();
auto prev = v.end();

while ( prev != v.begin() && *--prev == '\n' && prev != v.begin() && *--prev == '\r' )
{
    last = prev;
}

v.erase( last, v.end() );

std::cout << v.size() << std::endl;