2014-01-27 61 views
0

我想在向量的末尾削減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傳輸數據,這是writed向量,我需要func,這將需要一個指針向量和迭代器定義位置向後刪除CRLF。我認爲,我的所有問題顯然都包含在迭代器中。

+0

_'but但我的代碼不工作'_很模糊!改善你的問題... –

回答

0

您的代碼是至少由於設置不正確範圍算法的std ::無效等於

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; 
+0

它的工作,看起來不錯。這就是我想要的。謝謝。 – Slinner

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()); 
+0

它看起來像OP想要在字符串結尾刪除CRLF。您的版本將其移除。從問題中不清楚他是否希望僅刪除作爲序列出現的CRLF,或者最終刪除任何CR/LF字符。 – interjay

+0

@interjay真的。原帖的措詞不清楚。我將添加另一個版本,以便從最後刪除它。 –

+0

@Zac Howland,謝謝,它非常小巧,但我只需要刪除最後一個換行符,將其與第一個字符不同(從結尾處)。 P. S.我的算法與此類似,但從矢量的開頭清除這些字符可以正常工作。 – Slinner

0

,而是如果重新發明了個車輪可以在現有的STL算法中的東西,如:

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

如果您只是需要修剪掉結束'\r' & '\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; 
} 
+0

請注意,'std :: remove'實際上並沒有刪除這些元素,而只是將未刪除的元素放置在容器的開始處。 'std :: string.erase'可以在不需要循環的情況下進行實際刪除。 –

+0

@ZacHowland:耶,謝謝:) – LihO