Remove character from array where spaces and punctuation marks are found [duplicate]

StackOverflow https://stackoverflow.com/questions/21763038

  •  11-10-2022
  •  | 
  •  

Pergunta

In my program, I am checking whole cstring, if any spaces or punctuation marks are found, just add empty character to that location but the complilor is giving me an error: empty character constant.

Please help me out, in my loop i am checking like this

if(ispunct(str1[start])) {
    str1[start]=''; // << empty character constant. 
}
if(isspace(str1[start])) {
    str1[start]=''; // << empty character constant. 
}

This is where my errors are please correct me.

for eg the word is str,, ing, output should be string.

Foi útil?

Solução 4

Try this (as you asked for cstring explicitly):

char str1[100] = "str,, ing";

if(ispunct(str1[start]) || isspace(str1[start])) {
    strncpy(str1 + start, str1 + start + 1, strlen(str1) - start + 1);
}

Well, doing this just in pure language, there are more efficient solutions (have a look at @MichaelPlotke's answer for details).

But as you also explicitly ask for , I'd recommend a solution as follows:

Note you can use the standard c++ algorithms for 'plain' c-style character arrays also. You just have to place your predicate conditions for removal into a small helper functor and use it with the std::remove_if() algorithm:

struct is_char_category_in_question {
    bool operator()(const char& c) const;
};

And later use it like:

#include <string>
#include <algorithm>
#include <iostream>
#include <cctype>
#include <cstring>

// Best chance to have the predicate elided to be inlined, when writing 
// the functor like this:
struct is_char_category_in_question {
    bool operator()(const char& c) const {
        return std::ispunct(c) || std::isspace(c);
    }
};

int main() {
    static char str1[100] = "str,, ing";
    size_t size = strlen(str1);

    // Using std::remove_if() is likely to provide the best balance from perfor-
    // mance  and code size efficiency you can expect from your compiler 
    // implementation.
    std::remove_if(&str1[0], &str1[size + 1], is_char_category_in_question());

    // Regarding specification of the range definitions end of the above state-
    // ment, note we have to add 1 to the strlen() calculated size, to catch the 
    // closing `\0` character of the c-style string being copied correctly and
    // terminate the result as well!

    std::cout << str1 << endl; // Prints: string
}

See this compilable and working sample also here.

Outras dicas

There is no such thing as an empty character.

If you mean a space then change '' to ' ' (with a space in it).

If you mean NUL then change it to '\0'.

Edit: the answer is no longer relevant now that the OP has edited the question. Leaving up for posterity's sake.

If you're wanting to add a null character, use '\0'. If you're wanting to use a different character, using the appropriate character for that. You can't assign it nothing. That's meaningless. That's like saying

int myHexInt = 0x;

or

long long myIndeger = L;

The compiler will error. Put in the value you wanted. In the char case, that's a value from 0 to 255.

UPDATE:

From the edit to OP's question, it's apparent that he/she wanted to trim a string of punctuation and space characters.

As detailed in the flagged possible duplicate, one way is to use remove_copy_if:

string test = "THisisa test;;';';';";
string temp, finalresult;

remove_copy_if(test.begin(), test.end(), std::back_inserter(temp), ptr_fun<int, int>(&ispunct));
remove_copy_if(temp.begin(), temp.end(), std::back_inserter(finalresult), ptr_fun<int, int>(&isspace));

ORIGINAL

Examining your question, replacing spaces with spaces is redundant, so you really need to figure out how to replace punctuation characters with spaces. You can do so using a comparison function (by wrapping std::ispunct) in tandem with std::replace_if from the STL:

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

bool is_punct(const char& c) {
    return ispunct(c);
}

int main() {
    string test = "THisisa test;;';';';";
    char test2[] = "THisisa test;;';';'; another";

    size_t size = sizeof(test2)/sizeof(test2[0]);

    replace_if(test.begin(), test.end(), is_punct, ' ');//for C++ strings
    replace_if(&test2[0], &test2[size-1], is_punct, ' ');//for c-strings

    cout << test << endl;
    cout << test2 << endl;
}

This outputs:

THisisa test
THisisa test         another

As I don't like the accepted answer, here's mine:

#include <stdio.h>
#include <string.h>
#include <cctype>

int main() {
    char str[100] = "str,, ing";
    int bad = 0;
    int cur = 0;
    while (str[cur] != '\0') {
        if (bad < cur && !ispunct(str[cur]) && !isspace(str[cur])) {
                str[bad] = str[cur];
        }
        if (ispunct(str[cur]) || isspace(str[cur])) {
            cur++;
        }
        else {
            cur++;
            bad++;
        }
    }
    str[bad] = '\0';
    fprintf(stdout, "cur = %d; bad = %d; str = %s\n", cur, bad, str);
    return 0;
}

Which outputs cur = 18; bad = 14; str = string

This has the advantage of being more efficient and more readable, hm, well, in a style I happen to like better (see comments for a lengthy debate / explanation).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top