Ошибка утверждения на функции, использующей ispunct

Я получаю сбой утверждения после создания функции «ReplacePuncsWithBlanks». Это как-то связано с вставкой пробелов в начало и конец массива?

 #include <iostream>
#include <ctype.h>

using namespace std;

const int SIZE = 100;

void GetString(char StringArray[]);
void CopyString(char StringArray[], char CopiedArray[]);
void MakeUpper(char CopiedArray[]);
void InsertBlanks(char CopiedArray[]);
void ReplacePuncsWithBlanks(char CopiedArray[]);
void DisplayString(char StringArray[], char CopiedArray[]);

int main()
{
char StringEntered[SIZE];
char CopiedString[SIZE];

GetString(StringEntered);
CopyString(StringEntered, CopiedString);
MakeUpper(CopiedString);
InsertBlanks(CopiedString);
ReplacePuncsWithBlanks(CopiedString);
DisplayString(StringEntered, CopiedString);

cout<<"Hit Enter.\n";
cin.ignore();

}
/***************************************GetString********************************************
*   Action:         Prompts user to enter some text.                                        *
*                                                                                           *
*   Parameters:                                                                             *
*       IN:                                                                                 *
*                                                                                           *
*       OUT:        StringArray which is the array holding the original text inputted by    *
*                   the user                                                                *
*                                                                                           *
*   Returns:        Nothing.                                                                *
*                                                                                           *
*   Precondition:   StringArray points to StringEntered array in Main.                      *
*********************************************************************************************/
void GetString(char StringArray[])
{
cout<<"Please enter a sentence:  ";
cin.getline(StringArray, SIZE);
}/***************************************CopyString********************************************
*   Action:         Copies data from one array (StringArray) to another (CopiedArray).      *
*                                                                                           *
*   Parameters:                                                                             *
*       IN:         StringArray which has existing data.                                    *
*                                                                                           *
*       OUT:        CopiedArray which will be a copy of StringArray.                        *
*                                                                                           *
*   Returns:        Nothing.                                                                *
*                                                                                           *
*   Precondition:   StringArray points to StringEntered array in Main.                      *
*                   CopiedArray points to CopiedString array in Main.                       *
*********************************************************************************************/
void CopyString(char StringArray[], char CopiedArray[])
{
for(int i=0; i<SIZE; ++i)
{
CopiedArray[i]=StringArray[i];
}
}/**************************************MakeUpper*********************************************
*   Action:         Changes characters in the array to an uppercase letter.                 *
*                                                                                           *
*   Parameters:                                                                             *
*       IN:         CopiedArray which has mixed case letters.                               *
*                                                                                           *
*       OUT:        CopiedArray which will have uppercase letters.                          *
*                                                                                           *
*   Returns:        Nothing.                                                                *
*                                                                                           *
*   Precondition:   CopiedArray points to CopiedString array in Main.                       *
*********************************************************************************************/
void MakeUpper(char CopiedArray[])
{
char c;
for(int i=0; i<SIZE; ++i)
{
c=CopiedArray[i];
CopiedArray[i]=toupper(c);
}
}/***********************************InsertBlanks*********************************************
*   Action:         Moves elements in the array up one spot and replaces the first element  *
*                   with a space as well as the last element.
*                                                                                           *
*   Parameters:                                                                             *
*       IN:         CopiedArray prior to inserting the spaces.                              *
*                                                                                           *
*       OUT:        CopiedArray which will have a space in the first element and at the end.*
*                                                                                           *
*   Returns:        Nothing.                                                                *
*                                                                                           *
*   Precondition:   CopiedArray points to CopiedString array in Main.                       *
*********************************************************************************************/
void InsertBlanks(char CopiedArray[]){
int temp=0;
for (int i=SIZE-1; i>0; --i)
{
if(CopiedArray[i]=='\0')
{
temp=i+1;
}
CopiedArray[i]=CopiedArray[i-1];
}
CopiedArray[0]=' ';
CopiedArray[temp]=' ';
CopiedArray[temp+1]='\0';
}

/********************************ReplacePuncsWithBlanks**************************************
*   Action:         Changes characters which are punctuation to whitepaces.                 *
*                                                                                           *
*   Parameters:                                                                             *
*       IN:         CopiedArray which may include punctuation.                              *
*                                                                                           *
*       OUT:        CopiedArray which will have have replaced punctuations with whitespaces.*
*                                                                                           *
*   Returns:        Nothing.                                                                *
*                                                                                           *
*   Precondition:   CopiedArray points to CopiedString array in Main.                       *
*********************************************************************************************/
void ReplacePuncsWithBlanks(char CopiedArray[])
{
for (int i=0; i<SIZE; ++i)
{
if (ispunct(CopiedArray[i]))
{
cout<<CopiedArray[i];
}
}

}

void DisplayString(char StringArray[], char CopiedArray[])
{
for(int i=0; i<SIZE; ++i)
{
if(StringArray[i]!='\0')
{
cout<<StringArray[i];
}
else
{
i=(SIZE-1);
}
}
cout<<endl;

for(int x=0; x<SIZE; ++x)
{
if(CopiedArray[x]!='\0')
{
cout<<CopiedArray[x];
}
else
{
x=(SIZE-1);
}
}
cout<<endl;
}

Есть идеи о том, что это может быть?

1

Решение

В начале main функция, оба StringEntered а также CopiedString содержать мусор.

GetString Функция читает строку из ввода и заменяет начало из StringEntered с чем ты вошел. Затем следует \0 байт, а остальная часть мусора остается.

Потом, CopyString копирует ваш вклад, \0 байт и мусор в CopiedString,

Тогда функция ReplacePuncsWithBlanks работает с каждым байтом этого блока памяти. За каждый байт, который вы вызываете ispunctи эта функция очень особенная. Он не ожидает, что его аргумент будет иметь тип char (что вы, вероятно, думали), а скорее, чтобы быть типа unsigned char, Увидеть документация Больше подробностей.

Проблема в том, что char может иметь значение между -128 и 127 на вашей платформе, и мусор в конце строки, безусловно, содержит некоторые значения, которые являются отрицательными. Эти значения не допускаются в качестве аргументов ispunct функция.

Вам повезло, что вы получили ошибку утверждения. Ваша программа также могла молча потерпеть неудачу или взорвать ваш компьютер. Это называется неопределенное поведение.

Чтобы это исправить, вам нужно привести аргумент к нужному типу:

void ReplacePuncsWithBlanks(char CopiedArray[])
{
for (int i=0; i<SIZE; ++i)
{
if (ispunct((unsigned char)CopiedArray[i]))
{
cout<<CopiedArray[i];
}
}
}

Еще лучше было бы остановить цикл, как только вы увидите байт конца строки:

for (int i = 0; i < SIZE && CopiedArray[i] != '\0'; i++) {

Но даже тогда вам нужен приведение типа.

0

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

Других решений пока нет …

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