2014-02-09 1 views
1

Я получаю отказ утверждения после создания функции «ReplacePuncsWithBlanks». Имеет ли это какое-либо отношение к моей вставке пробелов в начало и конец массива?Утверждение Отказ от функции с использованием ispunct

#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

Можете ли вы показать код, который выделяет и заполняет 'CopiedArray', пожалуйста? Важное значение имеет также определение 'SIZE'. – simonc

+0

добавил остальную часть кода. спасибо, что посмотрели на него. – jstacy00

+0

Код работает для меня. Какой вклад вы предоставляете, чтобы сделать его неудачным? – simonc

ответ

0

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

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

Позже, CopyString копирует ваш вход, \0 байт и мусор на CopiedString.

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

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

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

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

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++) { 

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

 Смежные вопросы

  • Нет связанных вопросов^_^