c++, std::string::reverse_iterator, std::string::erase

Permalänk
Medlem

c++, std::string::reverse_iterator, std::string::erase

Hej försöker få std::string::erase att tabort massa mellanslag på slutet av en string detta är min test kod:

#include <vector> #include <iostream> #include <fstream> #include <string> #include "person.h" using std::istream; using std::ifstream; using std::vector; using std::cout; using std::endl; using std::string; istream& operator>>(istream& in, person& p); int main() { ifstream in("names.txt"); person temp_p; vector<string> p; string remove; string::reverse_iterator it; while(!in.eof()) { in>>temp_p; remove= temp_p.location.city; if(in.eof()) { break; } for(it = remove.rbegin(); it != remove.rend(); it++) { if(isspace((*it))) { remove.erase(*it); } else { break; } } p.push_back(remove); } for(int i = 0; i < p.size(); i++) { cout << p[i]; } cout << endl; return 0; }

den kommer in i if-satsen som inne håller std::string::erase men den lyckas inte ta bort mellanslagen.. någon som kan hjälpa mig förstå varför eller kanske tom en lössning?

tack så mycket i förväg!

kom på att man skulle skriva str.erase(*it); men de hjälpte inte fortfarande inge förändring.

byte även den andra if satsen till else sat istället

Visa signatur

Смерть -это решение всех проблем. Нет человека - нет проблемы
Comp1: Ubuntu 16.04 Comp2: Arch Linux
Comp3: Ubuntu Server 16.04 Comp4: Centos 6.5
Comp5: Linux mint 16 Comp6: Raspberry pi (olika OS hela tiden)
Phone: Motorola Google Nexus 6

Permalänk
Hedersmedlem

En alternativ lösning kan vara att använda string::find_last_not_of() för att hitta det sista relevanta tecknet.

Permalänk
Skrivet av Mejan:

kom på att man skulle skriva str.erase(*it); men de hjälpte inte fortfarande inge förändring.

Detta stämmer inte. *it är i detta fall av typen char.
remove.erase(*it) blir då remove.erase(' ') vilket tolkas som remove.erase(32)

Anledningen att inte remove.erase(it) fungerar är att string::erase inte fungerar med en reverse_iterator.
remove.erase(it.base()) fungerar dock.

Elgot lösning är dock ett bättre alternativ.

Permalänk
Medlem
Skrivet av Human_Metal:

Detta stämmer inte. *it är i detta fall av typen char.
remove.erase(*it) blir då remove.erase(' ') vilket tolkas som remove.erase(32)

Anledningen att inte remove.erase(it) fungerar är att string::erase inte fungerar med en reverse_iterator.
remove.erase(it.base()) fungerar dock.

Elgot lösning är dock ett bättre alternativ.

funkar utmärkt fast de blir

remove.erase(it.base()-1);

pga base för flyttar it ett steg framåt som man är tvungen att ta bort men de vart så min lössning vart tack så mmycket!

Visa signatur

Смерть -это решение всех проблем. Нет человека - нет проблемы
Comp1: Ubuntu 16.04 Comp2: Arch Linux
Comp3: Ubuntu Server 16.04 Comp4: Centos 6.5
Comp5: Linux mint 16 Comp6: Raspberry pi (olika OS hela tiden)
Phone: Motorola Google Nexus 6

Permalänk
Hedersmedlem
Skrivet av Mejan:

funkar utmärkt fast de blir

remove.erase(it.base()-1);

pga base för flyttar it ett steg framåt som man är tvungen att ta bort men de vart så min lössning vart tack så mmycket!

Även om man gör sådär är det dock förmodligen effektivare att spara positionen och radera alla oönskade tecken efter loopen istället för att radera ett i taget.

Permalänk
Medlem

jaså? jag får ta och kolla in de tack för tipset Elgot!

Visa signatur

Смерть -это решение всех проблем. Нет человека - нет проблемы
Comp1: Ubuntu 16.04 Comp2: Arch Linux
Comp3: Ubuntu Server 16.04 Comp4: Centos 6.5
Comp5: Linux mint 16 Comp6: Raspberry pi (olika OS hela tiden)
Phone: Motorola Google Nexus 6

Permalänk
Medlem

Vill även tacka Human_Metal

Visa signatur

Смерть -это решение всех проблем. Нет человека - нет проблемы
Comp1: Ubuntu 16.04 Comp2: Arch Linux
Comp3: Ubuntu Server 16.04 Comp4: Centos 6.5
Comp5: Linux mint 16 Comp6: Raspberry pi (olika OS hela tiden)
Phone: Motorola Google Nexus 6

Permalänk
Inaktiv

Tänkte bara passa på att posta lite gammal kod jag hade liggandes som jag skrev för jättelängesen. 2 metoder som är skriva för att ge ungefär samma funktionalitet som PHP's trim(). Dessa kommer inte kompilera out-of-the-box då jag klippt och klistrat ifrån en source-fil(utan headerdefinitioner osv), men kan ge lite insyn på ett alternativt (och mer reusable) sätt att göra om du orkar/vill "fixa" dom!

Har fler metoder liggandes ( liknande phps str_replace, explode osv) om du är intresserad, svara bara så postar jag en länk till en rar med hela biblioteket ist

std::string my::String::Trim(std::string line, my::String::TrimType type){ std::string returnline = line; bool doLeft; bool doRight; switch(type){ case my::String::LEFT: doLeft = true; doRight = false; break; case my::String::RIGHT: doLeft = false; doRight = true; break; case my::String::BOTH: doLeft = true; doRight = true; break; } std::vector<char> whitespace; whitespace.push_back(' '); whitespace.push_back('\n'); whitespace.push_back('\t'); whitespace.push_back('\r'); whitespace.push_back('\x0B'); whitespace.push_back('\0'); if(doLeft){ bool doneLeft = false; while(!doneLeft){ if(returnline.size() > 0){ bool doErase = false; for(std::vector<char>::iterator cit = whitespace.begin(); cit != whitespace.end(); ++cit){ if(returnline[0] == *cit){ doErase = true; } } if(doErase){ returnline = returnline.substr(1); }else{ doneLeft = true; } }else{ doneLeft = true; } } } if(doRight){ bool doneRight = false; while(!doneRight){ if(returnline.size() > 0){ bool doErase = false; for(std::vector<char>::iterator cit = whitespace.begin(); cit != whitespace.end(); ++cit){ if(returnline[returnline.size()-1] == *cit){ doErase = true; } } if(doErase){ returnline = returnline.substr(0, returnline.size()-1); }else{ doneRight = true; } }else{ doneRight = true; } } } return returnline; }; std::string my::String::Trim(std::string line, std::vector<char> whitespace, my::String::TrimType type){ std::string returnline = line; bool doLeft; bool doRight; switch(type){ case my::String::LEFT: doLeft = true; doRight = false; break; case my::String::RIGHT: doLeft = false; doRight = true; break; case my::String::BOTH: doLeft = true; doRight = true; break; } std::vector<char> whites = whitespace; if(doLeft){ bool doneLeft = false; while(!doneLeft){ if(returnline.size() > 0){ bool doErase = false; for(std::vector<char>::iterator cit = whites.begin(); cit != whites.end(); ++cit){ if(returnline[0] == *cit){ doErase = true; } } if(doErase){ returnline = returnline.substr(1); }else{ doneLeft = true; } }else{ doneLeft = true; } } } if(doRight){ bool doneRight = false; while(!doneRight){ if(returnline.size() > 0){ bool doErase = false; for(std::vector<char>::iterator cit = whites.begin(); cit != whites.end(); ++cit){ if(returnline[returnline.size()-1] == *cit){ doErase = true; } } if(doErase){ returnline = returnline.substr(0, returnline.size()-1); }else{ doneRight = true; } }else{ doneRight = true; } } } return returnline; };