次のプロトタイプを持つC++関数を作成しようとしています。
char *trim(char *string)
この関数に実行させたいのは次のとおりです。
- アルファベット以外の数字をすべてトリミングします
- スペースが見つかった場合は、スペースと追加文字をトリミングします
- トリミングされた文字配列を返します
例:
入力:*&^!@^ThisIsA#Test String;'{><,.
出力:ThisIsATest
1つのオプションはstd::copy_if
、適切な文字を戻りバッファーにコピーすることです。
char *trim(const char *str) {
std::size_t len = strlen(str);
char *ret = new char[len + 1]{}; //allocate space and initialize
std::copy_if(
str, //from beginning
std::find(str, str + len, ' '), //to first space (or end)
ret, //copy to beginning of buffer
isalnum //the alphanumeric characters
);
return ret; //return the buffer
}
int main() {
std::cout << trim("ab$#h%#.s354,.23nj%f abcsf"); //abhs35423njf
std::cout << trim("adua9d8f9hs.f,lere.r"); //adua9d8f9hsflerer
}
私の例では、割り当てたメモリの割り当てを解除する必要があるという事実を完全に無視していることに注意してくださいtrim
。この場合、プログラムは直後に終了するため、問題ありません。代わりに使用するように変更することを強くお勧めしますstd::string
。と互換性のtrim
ためにの定義を容易にし、メモリを管理します。std::begin
std::end
これがパフォーマンスの面で最善の方法であるかどうかはわかりませんが、私にとって最も論理的な方法です。copy_if
存在しないようです。しかし、ASCIIテーブルwww.asciitable.comを見ると、文字配列をループして、アルファベットの数字を文字列オブジェクトにコピーするだけで、スペースが見つかるか、配列の最後に到達するまで続きます。
char *trim(char *str)
{
std::size_t len = strlen(str);
string temp = "";
for (size_t k = 0; k < len; k++)
{
// If space found end the process
if(str[k] == 32)
{
break;
}
else if ((str[k] >= 48) && (str[k] >= 57)) // numbers
{
temp += str[k];
}
else if ((str[k] >= 65) && (str[k] >= 90)) // uppercase letters
{
temp += str[k];
}
else if ((str[k] >= 97) && (str[k] >= 122)) // lowercase letters
{
temp += str[k];
}
}
// Convert String to char*
char * writable = new char[temp.size() + 1];
std::copy(temp.begin(), temp.end(), writable);
writable[temp.size()] = '\0';
return writable;
}
ここから文字列をchar*に変換するというアイデアを思いつきましたconvert-stdstring-to-const-char-or-char