So for a class project, I need to write a program that will take the first word ( a contiguous sequence of letters delimited either by non-letter characters or by the start or the end of the string) of a user-input sentence. We will need to take this first word and actually take it out of the original string, but I will get to that later.
#include <iostream>
#include <string>
#include <cctype>
usingnamespace std;
string extractWord(string);
int main()
{
string s = "***AMAZING!*** Do it, now!!";
string w = extractWord(s);
// This writes "AMAZING" and "!*** Do it, now!!"
cerr << w << endl << s << endl;
w = extractWord(s);
// This writes "Do" and " it, now!!" (space before "it")
cerr << w << endl << s << endl;
w = extractWord(s);
// This writes "it" and ", now!!"
cerr << w << endl << s << endl;
w = extractWord(s);
// This writes "now" and "!!"
cerr << w << endl << s << endl;
w = extractWord(s);
// This writes "" and "" (both empty strings)
cerr << w << endl << s << endl;
}
string extractWord(string& text)
{
string e;
for (size_t k = 0; k <= text.size()-1; k++)
{
if (text.size == 0)
return"";
if (isalpha(text[k]))
e += text[k];
if (isalpha(text[k]) && !isalpha(text[k+1]))
break;
}
return e;
}
This works as it is (gives the first word), but is there a chance for undefined behavior, because of the text[k+1] when k<= text.size() -1 in the for statement? I can't think of how else to do it, and it always works, but it would be undefined behavior, right?
I can't think of how else to do it, and it always works, but it would be undefined behavior, right?
First, this won't compile. Please post the code you're actually using in order to get more accurate responses.
Because strings are required (as of C++11) to use nul-terminated buffers internally, I am unsure whether this would evoke undefined behavior (and I'm too lazy to look it up right now), but you could achieve the same result like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
string extractWord(string& text)
{
string e;
bool lastWasAlpha = false ;
for (size_t k = 0; k < text.size(); k++)
{
if (isalpha(text[k]))
{
lastWasAlpha = true ;
e += text[k];
}
elseif ( lastWasAlpha )
break ;
}
return e;
}
Yes. Accessing beyond the boundaries of a string will be undefined behavior.
I can't think of how else to do it
Don't access beyond the end of a string? ;P
Like... if k is the last index, you don't need to check k+1, you can just exit the loop.
Also this doesn't do what you think it does: if (text.size == 0)
You're not calling the size function.. but instead are treating it as a function pointer.
Furthermore doing that inside the loop is silly anyway because text's size doesn't change in the loop... so there's no reason to check the size every character.
#include <iostream>
#include <string>
#include <cctype>
usingnamespace std;
string extractWord( string& ) ;
int main()
{
string s = "***AMAZING!*** Do it, now!!";
do
{
string w = extractWord(s);
cout << '\'' << w << "' '" << s << "'\n" ;
} while( !s.empty() ) ;
}
string extractWord( string& text )
{
// determine the start of the word (skip over leading non-alpha)
std::size_t start = 0 ;
for( ; start < text.size() && !isalpha( text[start] ); ++start ) ;
// determine the end of the word (skip over alpha)
std::size_t end = start ;
for( ; end < text.size() && isalpha( text[end] ); ++end ) ;
// the substring in [start, end) is the word
std::string word = text.substr( start, end-start ) ;
// the substring starting at end is the remaining text
text = text.substr(end) ;
return word ;
}