Использование функции isalpha со строковыми указателями
Эй, я довольно новичок в программировании, и у меня возникают проблемы с использованием функции isalpha в моей программе. Это часть кода для класса палиндрома. То, что я пытаюсь сделать, это удалить все не алфавитные символы из ввода. Поэтому, если пользователь вводит "Привет, как дела", мне нужно сначала посчитать размер массива букв, а затем в моем подклассе removeNonLetters, мне нужно избавиться от неалфавитных символов. Может кто-нибудь, пожалуйста, помогите мне с этим. Спасибо вам большое!
#include <iostream>
#include <string>
#include <stdio.h>
#include <algorithm>
#include <cctype>
#include <cstring>
#include <ctype.h>
using namespace std;
class palindrome
{
private:
int only_letters_size;
string input_phrase;
string* only_letters;
public:
string inputPhrase();
string removeNonLetters();
string* new_Array;
int size_new_Array;
};
string palindrome::inputPhrase()
{
cout << "Input phrase: "; //asks the user for the input
getline(cin,input_phrase);
size_new_Array = input_phrase.length(); //creating a dynamic array to store
the input phrase
new_Array = new string[size_new_Array];
int i;
for (i=0; i<size_new_Array; i++)
{
new_Array[i]=input_phrase[i];
}
only_letters_size = 0;
while(new_Array[i])
{
if (isalpha(new_Array[i])) //PROBLEM OCCURS HERE
{
only_letters_size=only_letters_size+1;
}
}
cout << only_letters_size << endl;
return new_Array;
}
string palindrome::removeNonLetters()
{
int j=0;
int str_length = new_Array.length(); //string length
only_letters = new string[only_letters_size];
for (int i=0;i<size_new_Array;i++) //PROBLEM OCCURS HERE AS WELL
{
if (isalpha(new_Array[i]))//a command that checks for characters
{
only_letters[j] = new_Array[i];//word without non alphabetical c
characters is stored to new variable
j++;
}
}
cout << only_letters << endl;
return only_letters;
}
2 ответа
Я нашел лучший способ определить, является ли нить палиндромом, - идти к центру с обеих сторон. В вашем случае я бы предпочел пропустить не-альфа символы, как это.
bool is_palindrome(string mystring)
{
int start = 0, end = mystring.length() - 1;
while (start < end)
{
// Skip over non-alpha characters
while (!isalpha(mystring[start]))
{
start++;
}
while (!isalpha(mystring[end]))
{
end--;
}
if (tolower(mystring[start]) != tolower(mystring[end]))
{
return false;
}
else
{
start++;
end--;
}
}
return true;
}
Если вы должны сначала сохранить ввод и удалить неальфа-символы, я бы сделал это следующим образом.
string remove_non_alpha(string mystring)
{
string ret_string = "";
for (int i = 0; i < mystring.length(); i++)
{
if (isalpha(mystring[i]))
{
ret_string += tolower(mystring[i]);
}
}
return ret_string;
}
А затем введите результат в вышеуказанную функцию.
Извините за трудность, но вы слишком много копируете. Вы можете достичь всего этого с помощью одного цикла после извлечения ваших данных и всего на одном строковом объекте (если вы не хотите сохранить исходный ввод для каких-то других целей):
getline(cin,input_phrase);
std::string::iterator pos = input_phrase.begin();
for(char c : input_phrase)
{
if(isalpha(c))
{
*pos++ = tolower(c);
}
}
input_phrase.erase(pos, input_phrase.end());
После этого ваша строка готова к использованию...
Объяснение:
std::string::iterator pos = input_phrase.begin();
Итератор чем-то похож на указатель на внутренние данные строки. Мы сохраняем позицию для перемещения только буквенных символов, пропуская не-буквенные символы.
for(char c : input_phrase)
Просто перебирая все символы...
if(isalpha(c))
Основная проверка, является ли текущий символ альфа?
*pos++ = tolower(c);
Если это так, немедленно преобразуйте его в нижний регистр. Присвойте его текущей позиции строки и добавьте "указатель" (итератор!).
input_phrase.erase(pos, input_phrase.end());
И, наконец, отбросьте оставшуюся часть строки, занятую лишними символами. Вы можете заметить, что могут быть какие-то символы, которые вы хотели сохранить, но вы уже скопировали их в положение слева...