1

I'm doing a problem on HR and cant figure out how to check for error without using conditional statements. How is this done in C++?

// if string is int output it, else output "Bad string"
// need to do this without any loops/conditionals
int main(){
    string S;
    char *end;
    long x;
    cin >> S;
    const char *cstr = S.c_str();
    x = strtol(cstr,&end,10);

    if (*end == '\0')
        cout << x;
    else
        cout << "Bad string";

    return 0;
}

Should I be using something besides strtol?

Austin
  • 6,921
  • 12
  • 73
  • 138
  • 3
    [`std::stol`](http://en.cppreference.com/w/cpp/string/basic_string/stol) takes a `std::string` and throws an exception if the conversion couldn't take place. Also, your title says `int`, but your code uses `long`. It doesn't matter too much, but please correct one or other to be consistent. – BoBTFish Apr 21 '16 at 15:11
  • Can i make the exception a custom message if i use stoi? I actually need an int I was just testing with long. – Austin Apr 21 '16 at 15:13
  • 2
    You catch the exception (there are 2, for 2 different cases) and print out whatever you want. – BoBTFish Apr 21 '16 at 15:16
  • Hmm I've never seen that before. What function do you use to catch an exception? – Austin Apr 21 '16 at 15:17
  • 2
    Hm, exceptions might be a little beyond what you have learned so far then. There is a basic introduction [here](http://www.learncpp.com/cpp-tutorial/152-basic-exception-handling/), but it shows catching simple things like `int`s, you would need to `catch(std::invalid_argument const& e) { ... }`. A catch block has nothing to do with functions. – BoBTFish Apr 21 '16 at 15:20
  • What's wrong with what you have? – Lightness Races in Orbit Apr 21 '16 at 15:28
  • 1
    The specifications say it will be marked wrong if there are any loops or conditional statements. I guess I need to use `stoi` and then figure out how catching exceptions work. – Austin Apr 21 '16 at 17:55

2 Answers2

1

stoi is indeed what you'll want to use.

Given an input in string S one possible way to handle it would be:

try {
    cout << stoi(S) << " is a number\n";
} catch(const invalid_argument& /*e*/) {
    cout << S << " is not a number\n";
}

Live Example

The violation here is that stoi is only required to cosume the leading numeric part of the string not ensure that the entire string is an int. So "t3st" will fail cause it's not led by a number, but "7est" will succeed returning a 7. There are a handful of ways to ensure that the entire string is consumed, but they all require an if-check.

Community
  • 1
  • 1
Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • I think the while loop will mark it wrong, but thank you the catch line example is helpful – Austin Apr 22 '16 at 15:21
  • It worked! The try and catch blocks were what I needed, thanks. – Austin Apr 22 '16 at 15:27
  • @Jake I'm not sure what you mean, "the `while` loop will mark it wrong." It seems to work as expected in the example link. – Jonathan Mee Apr 22 '16 at 15:48
  • It works, but solutions that use loops or conditionals are automatically marked wrong for this problem on HackerRank. I got it working without the loop though, thanks. – Austin Apr 24 '16 at 20:26
  • @Jake Lol, the loop was extraneous to the problem anyway, I'll edit. – Jonathan Mee Apr 25 '16 at 04:38
0

One way would be:

char const *m[2] = { "Bad string", S.c_str() };
cout << m[*end == '\0'];
M.M
  • 138,810
  • 21
  • 208
  • 365
  • However innocent looking, the `==` is a conditional. If that's not considered an conditional statement, then I'd say the use of a ternary should be considered. – Jonathan Mee Apr 25 '16 at 11:19
  • @JonathanMee I assumed "conditional statement" meant a statement with the conditional operator, or an `if` / `while` / `for` – M.M Apr 25 '16 at 22:45