-4

I've got something like this. The problem is strings must be letters only, how can I do this? I've been sitting over this for few hours now and can't find any working solution. I've tried to use answers from this topic Accept only letters but I guess I'm too dumb and still can't make it work :(

#include <string>
#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>


using namespace std;

int main(void)
{
vector <string> strings;
string line;

do

{
cout << "enter string, 'stop' stops: ";
cin >> line;
strings.push_back(line);
}

while (line != "stop");

vector <string> :: iterator w;
cout << "Before sorting \n";
for (w=strings.begin(); w!=strings.end(); w++)
cout << *w << endl;

sort (strings.begin(),strings.end());
cout << "After sorting \n";
for (w=strings.begin(); w!=strings.end(); w++)

cout << *w << endl;

}
Community
  • 1
  • 1
  • In the while loop you need to iterate over the string and if a letter in it is not a letter you should not push it back in the vector of strings. To check whether a letter is alphabetic you can use `std::isalpha` http://www.cplusplus.com/reference/cctype/isalpha/ – 101010 Jun 18 '14 at 17:23
  • Your loop would be better off as `while ((std::cin >> line) && (line != "stop")) {strings.push_back(line);}`. That way you both don't get the extra element and you know the read succeeded before using the value. It's also really easy to add on another check for the string being only letters, or combining the condition into a `readString` function. – ghostofstandardspast Jun 18 '14 at 17:23
  • @40two, Rather than loop over it yourself, I would use `std::all_of`. – ghostofstandardspast Jun 18 '14 at 17:27
  • @ghostofstandardspast `std::all_of` is a loop too. – 101010 Jun 18 '14 at 17:29
  • 1
    @40two, Yes, I agree iterate over could mean that. I assumed you would have said the name if you were referencing an algorithm. If not, the benefits are that it's clear, efficient, and bug-free (at least extremely likely to be). – ghostofstandardspast Jun 18 '14 at 17:32
  • @ghostofstandardspast Good point. Your solution would not only have the advantage of being correct (which his isn't), but would avoid the annoying prompts for each line. – James Kanze Jun 18 '14 at 17:33
  • @JamesKanze, Oops, I didn't even see that in there. There's always the possibility it could be desired, in which case, it can be moved into said created function or before the read in the condition. In any case, I would much prefer it just telling me to enter *strings* instead of one at a time. I guess one could also take into account that mine would give an invalid input the same semantics as entering "stop", which again, could be changed. – ghostofstandardspast Jun 18 '14 at 17:36
  • @ghostofstandardspast _If_ it is desired to output the prompt each time (which I would detest as a user), then outputting the prompt and inputting the line should definitely be wrapped in a function. Beyond that, it's hard to say concerning the validation, for the reason you mention. If I were doing it, I might define a class `AlphaLine`, which had a `>>` operator, wrapped the string, and set `failbit` (but not `eofbit`) if it wasn't all alpha. But that seems like a bit much to throw at the OP all at once. (Why this solution: because it reports errors like all other input.) – James Kanze Jun 18 '14 at 17:53
  • @JamesKanze, Yes, that would be good come to think of it. – ghostofstandardspast Jun 18 '14 at 18:19

1 Answers1

1

You need to add validation code. For simple cases, you can do something like:

if ( std::find_if( line.begin(),
                   line.end(),
                   []( unsigned char ch ) { return !isalpha( ch ); }
        ) != line.end() ) {
    //  not all letters
}

(This is really only appropriate for school projects, and won't work for the usual network encoding, UTF-8.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • Is there any reason to prefer `std::find_if` to `std::all_of` (or perhaps `std::any_of` if you're testing the negation) besides `std::find_if` being available before C++11? I find those two to be slightly more clear as to what's being tested here. – ghostofstandardspast Jun 18 '14 at 17:34
  • @ghostofstandardspast Only that `std::find_if` doesn't require C++11. If you're sure of C++11, `std::any_of` is probably an even better choice. – James Kanze Jun 18 '14 at 17:45