问题
I am having a difficult time understanding this runtime error with my code. This was an assignment for my class that I thought would be easy, but something strange is gong on. I have posted my code below.
The prompt for this assignment was to create a program that asks the user to enter to enter some words, then it should output how many words there are. I have had a friend run the program and it worked, however, whenever I try to run it I get this runtime error. [ http://imgur.com/FcdN3zK ]
Please keep in mind that I am a beginner at C++ and programming in general, so I won't be able to understand very technical responses. Thank you in advance for your assistance.
#include <string>
#include <iostream>
#include <cstring>
using namespace std;
int wordCounter(char *);
int main()
{
char *stringArray = nullptr;
stringArray = new char[120];
cout << "Please enter a saying or a phrase that has more than one word: " << endl;
cin.getline(stringArray, 120);
int words = wordCounter(stringArray);
cout << "Your statement contains " << words << " words." << endl;
system("pause");
return 0;
}
int wordCounter(char *stringTest)
{
char characterToTest;
int numberOfWords = 0;
for (int i=0; i < 120; i++)
{
characterToTest = *(stringTest + i);
if (isspace(characterToTest) && i != 120)
{
char characterToTestTemp = *(stringTest + (i + 1));
if (isalnum(characterToTestTemp))
{
numberOfWords++;
}
}
}
return numberOfWords;
}
回答1:
You're not stopping at the termination of the input string, instead marching into non-input, indeterminate buffer data left at the tail end of our input buffer.
This is what you're likely trying to do:
int wordCounter(const char *str)
{
int numberOfWords = 0;
while (*str)
{
// skip any leading whitespace
while (*str && isspace(static_cast<unsigned char>(*str)))
++str;
// if we're still on string data, we have another word
if (*str)
{
// skip everything up to more whitespace
while (*str && !isspace(static_cast<unsigned char>(*str)))
++str;
// and count the word
++numberOfWords;
}
}
return numberOfWords;
}
Or something similar. Additional handling may need to be applied to account for punctuation, etc. This stops as soon as you reach the terminator of the input string.
Best of luck.
回答2:
isspace
and friends are surprisingly hard to call correctly. Specifically you can't safely pass a char
to them, because char
values can be negative and that is not allowed, as the error message says.
You should cast to unsigned char
to be safe:
isspace(static_cast<unsigned char>(characterToTest))
That isn't the main problem here, you need to fix the overrun first, but it's part of why you're getting the error message.
回答3:
Your wordcount function always process 120 characters regardless of the length of the input string really read. So your are reading past the end of the string and dealing with uninitialized memory.
Microsoft docyumentation reads "The behavior of _isctype and _isctype_l is undefined if c is not EOF or in the range 0 through 0xFF, inclusive. When a debug CRT library is used and c is not one of these values, the functions raise an assertion."
That's the reason for the assertion.
C strings are zero-terminated, you must test that condition into your loop.
int wordCounter(char *stringTest)
{
char characterToTest;
int numberOfWords = 0;
for (int i = 0; i < 120; i++)
{
characterToTest = *(stringTest + i);
if (characterToTest == 0)
break; // <-- exit the loop at the end of the string
if (isspace(characterToTest) && i != 120)
{
char characterToTestTemp = *(stringTest + (i + 1));
if (isalnum(characterToTestTemp))
{
numberOfWords++;
}
}
}
return numberOfWords;
}
you might have other logical bugs in your counting function, like not counting the first word.
回答4:
Thank you all for your help. Reading on this (and I do realize that I have logical errors that don't account for if a user enters nothing and submits it, it will still print 1), I was able to come up with a slightly different approach to this.
Here is the revised code.
#include <string>
#include <iostream>
#include <cstring>
using namespace std;
int wordCounter(char *, int);
int main()
{
cout << "Please enter a saying or a phrase that has more than one word: " << endl;
string testString;
getline(cin, testString);
int stringLength = testString.length();
char *stringArray = nullptr;
stringArray = new char[stringLength];
strcpy(stringArray, testString.c_str());
int words = wordCounter(stringArray, stringLength);
cout << "Your statement contains " << words << " words." << endl;
system("pause");
return 0;
}
int wordCounter(char *stringTest, int length)
{
char characterToTest;
int numberOfWords = 1;
for (int i=0; i < length; i++)
{
characterToTest = *(stringTest + i);
if (isspace(characterToTest) && (i != length))
{
char characterToTestTemp = *(stringTest + (i + 1));
if (isalnum(characterToTestTemp))
{
numberOfWords++;
}
}
}
return numberOfWords;
}
来源:https://stackoverflow.com/questions/28513332/debug-assertation-failed-c-1-c-255