1

The following code snippet is supposed to run through a vector of strings (words), and if the string contains an integer, it should push the int to an integer vector (nums) that contains only those numbers.

for (int i = 0; i < words.size(); i++){
    for(int j = 0; j < words.at(i).size(); j++){
        if (isdigit(words[i][j])){
            nums.push_back(words[i][j]);
        }
    }
    cout << words.at(i) << endl;
}

I've been given a file with the words on it. My code successfully pulls the words from the file and places them in a vector. However, my isdigit() function is not returning the expected values. The words are ho1d h4m, dance2, 8est, next, di6est, se3d, tes7 and my expected value for the nums vector is 1,4,2,8,6,3,7. Here's my print snippet:

for (int i = 0; i < nums.size(); i++){
        cout << nums.at(i) << " ";
    }

But it's returning the values 49 52 50 56 54 51 55. EDIT: Just recognized that these are the ascii values. How do I prevent them from pushing the ascii values instead of the integers? I've even tried to use the get() function and run through every character instead of every line while reading the input, and I still get the same values returned. Where am I going wrong?

quazi_moto
  • 449
  • 1
  • 3
  • 14
  • Look at those numbers. Do you see a pattern in how to convert those numbers to integers (even though ASCII values are integers)? Does the number `48` or character `'0'` come to mind? – PaulMcKenzie Sep 04 '18 at 02:22
  • There is a difference between the numerical values 0 to 9 and the characters `'0'` to `'9'`. – eesiraed Sep 04 '18 at 03:57
  • What is the code supposed to do if it finds two or more digits? Are they treated separately or as one larger integer? – Richard Hodges Sep 04 '18 at 07:41

2 Answers2

4

When you add the words[i][j] to the nums vector, you can do this:

nums.push_back(words[i][j] - '0');

Explanation: Since the first digit in the ASCII table is '0', you can subtract it from other digits (as char values) in order to get the difference as a number.

Here is a full example:

#include <vector>
#include <string>
#include <iostream>

int main() {
    std::vector<std::string> words = { "ho1d", "h4m", "dance2", "8est", "next", "di6est", "se3d", "tes7"};
    std::vector<int> nums;

    for (int i = 0; i < words.size(); i++){
        for(int j = 0; j < words.at(i).size(); j++){
            if (isdigit(words[i][j])){
                nums.push_back(words[i][j] - '0');
            }
        }
        std::cout << words.at(i) << std::endl;
    }

    for (int i = 0; i < nums.size(); i++){
        std::cout << nums.at(i) << " ";
    }
}

This code prints:

ho1d
h4m
dance2
8est
next
di6est
se3d
tes7
1 4 2 8 6 3 7 
HugoTeixeira
  • 4,674
  • 3
  • 22
  • 32
  • Thanks a ton. Could you explained why that worked? – quazi_moto Sep 04 '18 at 02:26
  • I have edited the post and added an explanation. Basically, the `0` char has code `48` and the other digits are `'1'=49`, `'2'=50`, `'3'=51`, etc. So if you substract, let's say, `'4'` (code=`52`) from `'0'`, the result is `4` (since `52 - 48 = 4`) as you wanted. – HugoTeixeira Sep 04 '18 at 02:32
  • It's not just ASCII. It's required by the language definition, regardless of the character encoding. The values of `'0'` through `'9'` are required to be contiguous and increasing, so `ch - '0'` always works when `ch` holds any of the characters `'0'..'9'`. – Pete Becker Sep 04 '18 at 11:40
-2

You can make use of atoi() like below:

  for (int i = 0; i < words.size(); i++)
  {
    for(int j = 0; j < words.at(i).size(); j++)
    {
        if (isdigit(words[i][j]))
        {
            char c = words[i][j];
            nums.push_back(atoi(&c));
        }
    }
    std::cout << words.at(i) << std::endl;
  }

for C++ you can use stoi stl function

Maddy
  • 774
  • 5
  • 14
  • 1
    Note `atoi` as used here will attempt to read multiple consecutive digits. For example, if the input contained `b10ck`, this would get the number `10` then the number `0` (where the original code would get the number `1` then the number `0`). – aschepler Sep 04 '18 at 02:46
  • `atoi` is completely unnecessary here. For a single digit, just subtract `'0'`. – eesiraed Sep 04 '18 at 03:56
  • @aschepler: Modified code to cover the scenario that you mentioned – Maddy Sep 04 '18 at 12:17
  • That change is no good, because now `&c` is not a null-terminated string. Really, just use `words[i][j] - '0'`. C++ does guarantee `isdigit` will only return truthy for the ten ordinary digit characters regardless of locale, and that those ten digit characters have consecutive numeric values, even if those values are not consistent with ASCII. – aschepler Sep 04 '18 at 12:46