Удаление пробелов из массива char / cstring?

Я не могу заставить свою программу удалить лишние пробелы, найденные в предложении, например, если после пробела есть еще один пробел. И цикл while, который я использую, чтобы попросить пользователя продолжить, препятствует запуску функций. Когда я удаляю его, остальная часть программы запускается.

Это основная функция:

int main()
{
bool program_start = 1;
char user_sentence[MAX];

cout<<"This program will take any sentence you write and correct any spacing\n"<<" or capitalization (not proper nouns) mistakes you have.\n";

while(loop_continue(program_start))
{
input(user_sentence, MAX);
uppercase_spacing(user_sentence);
lowercase(user_sentence);
cout<<user_sentence;
}

return 0;
}

Моя проблема с моей функцией uppercase_spacing, я не могу заставить ее удалить лишние пробелы, которые находятся внутри предложения.

Вот функции void, которые я использую для редактирования предложений:

void uppercase_spacing(char sentence[])
{
int number = 0;
if(isspace(sentence[0]))
{
for(int i = 0; i < MAX; i++)
{
sentence[i] = sentence[i + 1];
}

while(number<MAX)
{
if((isspace(sentence[number])) && (isspace(sentence[number+1])))
{
sentence[number] = sentence[number + 1];
}
number++;
}

sentence[0] = toupper(sentence[0]);

}else{

for(int index = 0; index<MAX;index++)
{
if((isspace(sentence[index])) && (isspace(sentence[index+1])))
sentence[index]=sentence[index+1];
}

sentence[0] = toupper(sentence[0]);

}
return;
}

void lowercase(char sentence[])
{
for(int i = 1; (i < MAX) && (i != '\0'); i++)
{
sentence[i] = tolower(sentence[i]);
}

return;
}

Я использую это логическое значение во всех других моих программах, поэтому я считаю, что проблема заключается в основной части программы.

Вот логическая функция, которую я использую для цикла while:

bool loop_continue(bool another_round)
{
bool again = another_round;
char continue_loop = 'y';
cout<<"Would you like to continue? Type y or Y for yes,\n">>" or any other letter for no.\n";
cin>> continue_loop;
if((continue_loop == 'y' )||(continue_loop == 'Y'))
{
cout<<"Okay, let's do this!"<<endl;
again = 1;
}else
{
cout<<"Goodbye."<<endl;
again = 0;
}
return again;
}

Вход; кавычки должны заменить пробелы.

Candy CCandy «» «» что-то

Выход; места все еще там:

Candy Ccandy «» «» что-то

0

Решение

Во-первых, в вашем коде есть несколько отдельных ошибок. (Максимальный индекс в char sentence[MAX] является MAX-1и у вас есть несколько случаев, когда тело цикла работает с index=MAX-1 и вы получаете доступ sentence[index+1]).

Во-вторых, давайте углубимся в то, что делает ваша функция …

for(int index = 0; index<MAX;index++)
{
// if sentence[index] and sentence[index+1] are both spaces....
if((isspace(sentence[index])) && (isspace(sentence[index+1])))
// set sentence[index] to sentence[index+1] (??!)
sentence[index]=sentence[index+1];

// now proceed to the next character
}

Вы видите проблему сейчас? Вы устанавливаете символ, известный как пробел (sentence[index]) персонажу, который известен как пробел (sentence[index+1]). Вы на самом деле не удаляете пробелы.

1

Другие решения

void compress_spaces( char *src)
{
char *dst = src;

// skip leading spaces first
while( isspace( *src ))
src ++;

int space = 0;  // a character recently copied was a space

for( ; *src; src++ )
if( isspace( *src ))
{
if( !space )    // append a space only after a non-space char
*dst++ = *src;
space = 1;
}
else
{
*dst++ = *src;  // apped a non-space char always
space = 0;
}

if( space )    // truncate the terminating space
dst--;
*dst = 0;      // terminate the resulting string
}
1

Причина, по которой ничего не происходит, заключается в том, что вы просто заменяете пробел другим пробелом, когда находите два пробела подряд. Назначение, которое вы делаете, на самом деле не сдвигает остальную часть массива, оно просто заменяет значение в [число] значением в [число + 1]:

if((isspace(sentence[number])) && (isspace(sentence[number+1])))
{
sentence[number] = sentence[number + 1];
}

Когда вы находите два пробела в строке, как это, вам нужно ввести внутренний цикл, чтобы найти первый символ, который не является пробелом, а затем сдвинуть этот символ (и все последующие символы) вниз до исходного пробела.

0

Проблема в том, что когда вы находите пару предложений в предложении, вы просто копируете одно поверх другого, ничего не удаляя, поэтому у вас все еще остается пара пробелов. То, что вы хотите, это скопировать все после дополнительного пространства вниз, чтобы избавиться от пространства. Что-то вроде:

void uppercase_spacing(char sentence[]) {
char *in, *out;

in = out = sentence;
while (*in) {  /* while there's more sentence... */
while(isspace(*in)) in++;  /* skip any initial spaces */
while (*in && !isspace(*in))  /* copy non-spaces */
*out++ = toupper(*in++);   /* convert to upper case */
*out++ = *in;  /* copy a single space or the end of the string */
}
if (--out > sentence && isspace(*--out))
*out = 0;  /* trim off trailing space, if any */
}
0

Еще одна проблема, с которой вы столкнулись MAX персонажей, хотя их может быть меньше.

Например, если MAX равен 1500, и я ввожу предложение «Помоги мне!», Которое составляет 9 символов (8 букв + 1 для нулевого терминатора), ваша программа будет искать 1500 символов.

Я предлагаю вам инвестировать в некоторые библиотечные функции, такие как:
std::strchr — найти символ в C-строке (например, пробел).
std::memmove — копирует символы из одного места в другое, особенно если места перекрываются.
std::strlen — возвращает количество символов в строке.

0
По вопросам рекламы [email protected]