Removing a character from a string - c++

i have a string. I want to delete the last character of the string if it is a space.
i tried the following code,
str.erase(remove_if(str.begin(), str.end(), isspace), str.end());
but my g++ compiler gives me an error saying:
error: no matching function for call to ‘remove_if(__gnu_cxx::__normal_iterator<char*,
std::basic_string<char, std::char_traits<char>, std::allocator<char> > >,
__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>,
std::allocator<char> > >, <unresolved overloaded function type>)’
please help.

The first problem is that isspace has multiple overloads in the C++ Standard Library. The initial fix is to provide an explicit type for the function so that the compiler knows which function to take the address of:
#include <string>
#include <algorithm>
#include <cctype>
int main()
{
std::string str = "lol hi innit";
str.erase(std::remove_if(str.begin(), str.end(), (int(*)(int))isspace), str.end());
std::cout << str; // will output: "lolhiinnit"
}
It's a big ugly but, hey, this is C++.
Second, your code will remove all spaces in the string, which is not what you seem to want. Consider a simple if statement on the last character of the string:
#include <string>
#include <cassert>
int main()
{
std::string str = "lol hi innit ";
assert(!str.empty());
if (*str.rbegin() == ' ')
str.resize(str.length()-1);
std::cout << "[" << str << "]"; // will output: "[lol hi innit]"
}
Hope this helps.

I think it can't figure out what isspace is (according to the "unresolved overloaded function type" as a third parameter to remove_if in the error message). Try ::isspace, and include ctype.h

I had the exact same problem as you, so I got rid of isspace. I just went with this:
str.erase(std::remove_if(str.begin(),str.end(),' '),str.end());
That worked for me with Visual C++ 2012, using Visual Studio 2012. See if it works for you.

You are missing an std:: for remove_if

Related

error in reading input stream read in c++ with visual studio code

#include<iostream>
#include<string>
#include<cstdlib>
#include<sstream>
#include<vector>
#include <iterator>
using namespace std;
int main()
{
string str;
unsigned int i;
vector<string> arr;
getline(cin,str);
istringstream it(str);
vector<string> arr(istream_iterator<string>(),istream_iterator<string>(it));
arr.push_back('\0');
//boost::split(arr, str, [](char c){return c == ' ';});
//auto splitText = str | view::split(' ');
for(i=0; i<arr.size(); i++){
cout<<arr[i]<<endl;
}
return 0;
}
The above code shows an error as follows:
error: 'std::vector > arr(std::istream_iterator > (*)(), std::istream_iterator >)' redeclared as different kind of symbol
when building with g++. Any help or hint would be highly appreciated.
When running g++, it also hints at where the problem lies:
a.cpp:13:20: note: previous declaration 'std::vector<std::__cxx11::basic_string<char> > arr'
vector<string> arr;
^~~
This means, you declared arr twice. First at line 13 and a second time at 17.
This is what
redeclared as different kind of symbol
means.
Removing the first declaration at line 13, fixes this error message, but reveals the next problem
a.cpp:18:9: error: request for member 'push_back' in 'arr', which is of non-class type 'std::vector<std::__cxx11::basic_string<char> >(std::istream_iterator<std::__cxx11::basic_string<char> > (*)(), std::istream_iterator<std::__cxx11::basic_string<char> >)'
arr.push_back('\0');
^~~~~~~~~
This is more complicated, and is why #DietmarKühl closed the question as a duplicate to question Most vexing parse: why doesn't A a(()); work?. The second answer is the most useful in this case and solves it by using curly braces around the parameters
vector<string> arr{istream_iterator<string>(),istream_iterator<string>(it)};

Unordered_map<string, int> works but Unordered_map<string, string> does not

I don't understand why the second block of code in this short example does not compile correctly. It is my understanding that the second parameter in the <> represents the value, which doesn't need to be unique. Why is the second block of code throwing a compiler error, and what do I need to do to remedy it?
// Unordered Map example .cpp
#include <stdio.h>
#include <string>
#include <cstring>
#include <unordered_map>
using namespace std;
int main(void) {
// This works as expected
unordered_map<std::string, int> m;
m["foo"] = 42;
printf("%i\n", m["foo"]);
// This this doesn't compile
unordered_map<std::string, std::string> m1;
m1["foo"] = "42";
printf("%s\n", m1["foo"]);
return 0;
}
I am compiling this code on CentOS 5.8 using
g++44 -c -Wall -std=c++0x -g map_example.cpp
and these are the errors I am getting
map_example.cpp: In function ‘int main()’:
map_example.cpp:20: warning: cannot pass objects of non-POD type ‘struct std::basic_string<char, std::char_traits<char>, std::allocator<char> >’ through ‘...’; call will abort at runtime
map_example.cpp:20: warning: format ‘%s’ expects type ‘char*’, but argument 2 has type ‘int’
If I am having trouble with a basic c++ class such a std:string what do I need to do to have a custom class as a value, where can I find a fully implemented minimal example?
printf does not work with std::string. Either use cout << m1["foo"] or printf("%s", m1["foo"].c_str())
printf("%s\n", m1["foo"]); is C.
For c++ you should use std::cout to have both the string and the int map's values printed out as expected.
The compiler cannot do a translation for a std::string object automatically to const char* (there is no conversion to const char* by default: Why does std::string not provide a conversion to const char*?)

Boost::regex_match fails

I need to use regular expression matching in my program. I decided to use boost library for it, but I receive strange fail when trying to compile. What is wrong??
There is my code:
...
#include <boost/regex.hpp>
...
using namespace boost;
...
map <string, double>::iterator container::find (string toFind)
{
iterator it;
for (it=mainMap.begin(); it!=mainMap.end(); it++)
{
regex e ((*it).first); //this line works correct
if ( regex_match (toFind, e ) )
return it;
}
return it;
}
...
Error message is to big for posting, there is its beginning:
tmp/cczkfDcy.o(.gnu.linkonce.t._ZN5boost11basic_regexIcNS_12regex_traitsIcEESaIcEED1Ev+0x11):
In function boost::basic_regex<char, boost::regex_traits<char>,
std::allocator<char> >::~basic_regex()': : undefined reference to
boost::reg_expression,
std::allocator >::~reg_expression()' ...
Add:
-lboost_regex
to your compiler options.

C++: What error in using STL vector

I was using the topcoder C++ compiler, and although this code just run fine in Linux gcc, the topcoder compiler gave this error:
your code did not compile:
errors compiling:
Your class or method was improperly declared: In function
‘std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > _wrapper::thunk(std::string)’:
Your class or method was improperly declared:20034:
error: conversion from ‘void’ to non-scalar type
‘std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >’ requested
This is the code snippet where it is flagging error:
class BinaryCode {
public:
static int get_digit(char c)
{
return (c-'0');
}
void decode(string decd)
{
int i;
std::vector <int> decoded(decd.size());
std::transform(decd.begin(), decd.end(), decoded.begin(), &get_digit);
int length=decoded.size();
This is the topcoder problem description:
Definition Class:BinaryCode
Method:decode
Parameters:string
Returns:vector <string>
Method signature:
vector <string> decode(string message)
(be sure your method is public)
    
Your method signature is:
void decode(string decd)
Should be:
vector <string> decode(string message)
TopCoder compiles your code with testing code for the problem. Make sure the code you provide meets the requirements in the problem statement.
Topcoder compiler is expecting the function to be
vector <string> decode(string message)
while your function is
void decode(string message)
You are using 'void' instead of vector < string >
Try to use
using namespace std;
it fixed my problem. And also includes, it puts your code into separate file
#include <vector>
#include <string>

Boost ( 1.34) Regex syntax bug

I have read some amount of documentation, and I am more familiar with the current version being shipped with VS2010. But for now I am stuck with ubuntu 8.04, and boost 1.34 and am getting some weird sort of error. Can anybody tell what I am doing wrong. Here is the man page for regex_search boost v1.34
Here is what I am doing in my code :
std::string sLine;
getline(dataFile, sLine);
boost::match_results<std::string::const_iterator> lineSmatch;
boost::match_flag_type regFlags = boost::match_default;
boost::regex finalRegex(linePattern);
boost::regex_search(sLine.begin(), sLine.end(), lineSmatch, finalRegex, regFlags);
Here is the compilation error:
error: no matching function for call to 'regex_search(__gnu_cxx::__normal_iterator, std::allocator > >, __gnu_cxx::__normal_iterator, std::allocator > >, boost::match_results<__gnu_cxx::__normal_iterator, std::allocator > >, std::allocator, std::allocator > > > > >&, boost::regex&, boost::regex_constants::match_flag_type&)'
If you are going to apply regex_search to sLine itself instead of
iterator range, as Howard answered, you can use sLine instead of
begin() and end().
For example:
boost::regex_search(sLine, lineSmatch, finalRegex, regFlags);
If you have to give iterator range to regex_search, since the type
argument for match_results is const_iterator, the first and second
arguments for regex_search need to be const_iterator too.
For example:
std::string::const_iterator b = sLine.begin(), e = sLine.end();
boost::regex_search(b, e, lineSmatch, finalRegex, regFlags);
Hope this helps
Can't help you specifically with ubuntu 8.04, and boost 1.34. However the following compiles for me on libc++ which implements C++11. Perhaps it is close enough to your environment to tell you what is wrong.
#include <regex>
#include <fstream>
int main()
{
std::ifstream dataFile;
std::string sLine, linePattern;
getline(dataFile, sLine);
std::match_results<std::string::const_iterator> lineSmatch;
std::regex_constants::match_flag_type regFlags =
std::regex_constants::match_default;
std::regex finalRegex(linePattern);
std::regex_search(sLine, lineSmatch, finalRegex, regFlags);
}