3

I'm trying to remove all punctuation characters from a std::string in C++. My current code:

string str_in; string::size_type i, j; cout << "please input string with punctuation character..." << endl; cin >> str_in; for (i = 0, j = 0; i != str_in.size(); ++i) if (!ispunct(str_in[i])) str_in[j++] = str_in[i]; str_in[j] = '\0'; cout << str_in << endl; 

Is str_in[j] = '\0'; wrong?

3
  • I agree that str_in[j] = '\0' is wrong since that's not an appropriate way to terminate a std::string. What is the question? Commented May 28, 2012 at 5:40
  • How to terminate a std::string in c++ Commented May 28, 2012 at 5:43
  • It would be helpful if you'd rephrase the question. Unlike C-style strings, std::strings are not defined to use a terminator. I think you're trying to delete all punctuation marks from a std::string, so "foo.bar+baz" becomes "foobarbaz". If so, that has nothing to do with termination. Commented May 28, 2012 at 6:50

4 Answers 4

4

If you want to truncate str_in to the first j characters, you can say str_in.resize(j).

If you want to use the standard library you could apply the erase-remove idiom like this:

#include <algorithm> #include <iostream> #include <string> int main() { std::string str_in; std::getline(std::cin, str_in); // Here is where the magic happens... str_in.erase(std::remove_if(str_in.begin(), str_in.end(), ::ispunct), str_in.end()); std::cout << str_in << '\n'; return 0; } 
Sign up to request clarification or add additional context in comments.

1 Comment

The erase/remove_if idiom is, of course, the only reasonable way of solving this problem in C++. But passing ::ispunct as the predicate results in undefined behavior, since you cannot safely call ::ispunct with a char. (The input to ::ispunct must in the range [0, UCHAR_MAX] or be EOF.)
1

the C++ string type is NOT implemented to be null terminated (although a c_str() call will give you a null terminated string.)

So yes, str_in[j] = '\0' is wrong for at least two reasons:

  1. The str_in.length() will not reflect the size of the string you expect with the punctuation removed.
  2. The null charatcter is an extra charter which will be sent to any output stream,
    such as cout << str_in;

Using the std::string class you should probably not oveeride the same buffer, but probably use a str_out buffer instead which will have the right length after you copy all the wanted (i.e. excluding the punctuation character), OR you should instead adjust the length of the str_in instead of adding the null.

Comments

0

I think str_in[j] = '\0' is wrong when the string has no any punctuation.

2 Comments

It's not an appropriate way to terminate a std::string anyway. str_in.size() would return the wrong value, for example.
@jamesdlin oh,yes. It is std::string, not the char[]. I forget it.
0

Instead of modifying the same string, create a new string (e.g. str_out) and append to that:

str_out += str_in[i]; 

3 Comments

I know this method, I just want to use the same string to achieve the function.
@iverson Then either copy to str_in when done, or use substr: str_in = str_in.substr(0, j);
Or just say str_in.resize(j)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.