Я получаю сбой утверждения после создания функции «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;
}
Есть идеи о том, что это может быть?
В начале 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++) {
Но даже тогда вам нужен приведение типа.
Других решений пока нет …