Eliminate punctuations and whitespace

192 Views Asked by At

I am new to c++ programming and would like to write a program which has the following requirement:

Given a text consists of

  • words
  • letters
  • numbers
  • punctuations, and
  • whitespaces.

Filter out any characters that not in the range of 0..9, a..z or A..Z.

This means that when I typed in:

The quick brown fox jumps over the lazy dog!

The output will be:

Thequickbrownfoxjumpsoverthelazydog

I have typed the following codes and try to run it and the outcome is fine. However, when I submitted it onto another c++ platform for checking the validity, there is no output to be generated.

I am so confused... Please help if you could. Thank you very much to you all.

#include <iostream>
#include <string>
using namespace std;

int main()
{
    string line;
    getline(cin, line);
    for (int i = 0; i < line.size(); ++i)
    {
        if (!((line[i] >= 'a' && line[i] <= 'z') || (line[i] >= 'A' && line[i] <= 'Z') || (line[i] >= '0' && line[i] <= '9')))
        {
            line[i] = '\0';
        }
    }
    cout << line;
    return 0;
}
3

There are 3 best solutions below

0
On

\0 is the end of a string, so when you use this, you are cutting off your string at the first occurence.

You'd better remove that char from your array, but then I'd advise you to go from the end back to the beginning:

Pseudo-code:

for i = size(line)-1 back to i = 0:
  if line[i] in ('a'-'z', 'A'-'Z', ...):
    for j = i to size(line)-1:
      line[j] = line[j+1]
   reduce_by_the_last_character(line)
3
On

If you want to remove the characters other than letters and digits, the better choice would be using erase–remove idiom.

  1. Use std::isalnum to check the character in the string is either an alphabet or a numeric. If you pack it into a unary predicate(lambda function), you can apply to the following algorithm function.
  2. Using std::remove_if, and the above-mentioned predicate, collect all characters in the string, which had to be removed.
  3. Lastly, using std::string::erase remove all the characters which have been collected by std::remove_if.

Something like as follows: See a demo here

#include <cctype>     // std::isalnum
#include <algorithm>  // std::remove_if

std::string str{ "The quick brown fox jumps over the lazy dog!" };

// predicate to check the charectors
const auto check = [](const char eachCar)->bool { return !std::isalnum(eachCar); };

// collect the chars which needed to be removed from the string
const auto charsToRemove = std::remove_if(str.begin(), str.end(), check);

// erase them out
str.erase(charsToRemove, str.end());

Disclaimer: The above solution does not cover OP's concern(@john has explained it well in his answer), rather it could be helpful for future readers.

6
On

Your code just replaces one character with another. The simple way to erase characters from a string is to use the erase method. Something like this

#include <iostream>
#include <string>
using namespace std;

int main() 
{
    string line;
    getline(cin, line);
    for (int i = 0; i < line.size(); )
    {
        if (!((line[i] >= 'a' && line[i]<='z') || (line[i] >= 'A' && line[i]<='Z')||(line[i] >= '0' && line[i]<='9')))
        {
            line.erase(i, 1);
        }
        else
        {
            ++i;
        }
    }
    cout << line; 
    return 0;
}

Note that the code only adds one to i when we don't erase a character, otherwise you'd skip the character after the one erased because the string is now one shorter.