3

This should accept only letters, but it is not yet correct:

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main()
{
    std::string line;
    double d;

    while (std::getline(std::cin, line))
    {
        std::stringstream ss(line);
        if (ss >> d == false && line != "") //false because can convert to double
        {
            std::cout << "its characters!" << std::endl;
            break;
        }
        std::cout << "Error!" << std::endl;
    }
    return 0; 
}



Here is the output:

567
Error!

Error!
678fgh
Error!
567fgh678
Error!
fhg687
its characters!
Press any key to continue . . .

fhg687 should output error because of the numbers in the string.

Accepted output should contain letters only, such as ghggjh.

Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
sg552
  • 1,521
  • 6
  • 32
  • 59
  • Do you mean only alphabetical characters, or should it also accept things like punctuation? – Jerry Coffin Dec 08 '12 at 16:23
  • Yes only alphabetical. No !, @, ? etc. etc. – sg552 Dec 08 '12 at 16:24
  • In that case, this is *nearly* identical to a couple of [previous](http://stackoverflow.com/q/13080003/179910) [questions](http://stackoverflow.com/q/8888748/179910). The primary change would be substituting `isalpha` for `isdigit`. – Jerry Coffin Dec 08 '12 at 16:49
  • Yes you are correct. Previous question ask for digits. – sg552 Dec 08 '12 at 16:51

3 Answers3

12

You'd be much better off using std::all_of on the string, with an appropriate predicate. In your case, that predicate would be std::isalpha. (headers <algorithm> and <cctype> required)

if (std::all_of(begin(line), end(line), std::isalpha))
{
    std::cout << "its characters!" << std::endl;
    break;
}
std::cout << "Error!" << std::endl;
Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
7

Updated: to show a fuller solution.

The simplest approach would probably be to iterate through each char in the input and check whether that char is within English-letter ranges in ascii (upper + lower):

char c;

while (std::getline(std::cin, line))
{
    // Iterate through the string one letter at a time.
    for (int i = 0; i < line.length(); i++) {

        c = line.at(i);         // Get a char from string

        // if it's NOT within these bounds, then it's not a character
        if (! ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) ) ) {

             std::cout << "Error!" << std::endl;

             // you can probably just return here as soon as you
             // find a non-letter char, but it's up to you to
             // decide how you want to handle it exactly
             return 1;
        }
     }
 }
sampson-chen
  • 45,805
  • 12
  • 84
  • 81
  • 2
    There's also `std::isalpha()` – Cornstalks Dec 08 '12 at 16:33
  • @Cornstalks oh neat! I saw saw that while reading Benjamin's answer - learned something new today =) – sampson-chen Dec 08 '12 at 16:35
  • @sampson-chen Could you please check my code here http://ideone.com/2CVw36. Even after I make the change the `fhg687` is still a `character`. Thank you. – sg552 Dec 08 '12 at 17:08
  • @sg552: The problem is that you were not iterating through the characters in your string (meaning: looking at each character one at a time). See my updated answer for a fuller solution to see what you need to change. – sampson-chen Dec 08 '12 at 17:19
  • `line` already is a string, so why not just use that directly and eliminate the `stringstream` altogether? – Benjamin Lindley Dec 08 '12 at 17:30
  • @BenjaminLindley Oh good catch! =p I need to sleep more; fixing that now – sampson-chen Dec 08 '12 at 17:41
2

You can also use regular expressions, which may come in handy if you need more flexibility.

For this question, Benjamin answer is perfect, but just as a reference, this is how regex could be used (notice that regex is also part of the C++11 standard):

boost::regex r("[a-zA-Z]+");  // At least one character in a-z or A-Z ranges
bool match = boost::regex_match(string, r);
if (match)
    std::cout << "it's characters!" << std::endl;
else
    std::cout << "Error!" << std::endl;

If string contains only alphabetic characters and at least one of them (the +), then match is true.

Requirements:

  • With boost: <boost/regex.hpp> and -lboost_regex.
  • With C++11: <regex>.
Vincenzo Pii
  • 18,961
  • 8
  • 39
  • 49