在构建“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;
}
关于它可能是什么的任何想法?
答案 0 :(得分:0)
在main
函数的开头,StringEntered
和CopiedString
都包含垃圾。
GetString
函数从输入中读取一行,并用您输入的内容替换StringEntered
的开头。然后是一个\0
字节,其余的垃圾仍然存在。
稍后,CopyString
会将您的输入,\0
字节和垃圾复制到CopiedString
。
然后,函数ReplacePuncsWithBlanks
对该内存块的每个字节进行操作。对于您调用ispunct
的每个字节,此功能非常特殊。它不期望它的参数是char
类型(您可能认为),而是类型unsigned char
。有关详细信息,请参阅documentation。
问题是,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++) {
但即便如此,你还需要输入类型。