简体   繁体   中英

C++ passing integer parameter to function and converting to char for conditional

int number is a paramter for the function this code is from. first_digit is a string that has been passed the first value from a ifstream file

else if (number != 0)
    {
        std::string number_string = std::to_string(number);
            while (!file.eof() )
            {
                if (first_digit[0] == number_string)
                {
                    count++;
                }
            file >> first_digit;
            }

What I am trying to do is have count++ iff the first digit from the file matches the char value of parameter int number . AKA I am trying to count the lines for which the first digit matches number . number is passed from a separate function that will send number for(i=1;1<10;i++) so that I will end with a total sum for the number of times the first digit in the file is 1, 2, 3 etc etc

What I am struggling with is the conditional! How can I relate the first index position of string first_digit to int n on the basis of they hold the same char value? eg '1' == '1' therefore count++

The numeric values of digit characters are guaranteed to be increasing and consecutive. In other words, I believe you're looking for this:

if (first_digit[0] == '0' + number) {
  //...
}

What you are attempting to do will only work if number is between 0 and 9. Additionally, if first_digit is a string , then first_digit[0] is a char , which you are then trying to compare to a string (which will not work).

else if (number > 0 && number <= 9) // no sense in checking larger numbers unless you convert the base
{
    std::string number_string = std::to_string(number);
    std::string line;
    while (std::getline(file, line))
    {
        if (line[0] == number_string[0])
        {
            count++;
        }
    }
}

Or, alternatively, you could use std::count_if to do it all for you instead of writing your own loop. It would look something like the following (NOTE: This has not been debugged):

struct line_reader : std::ctype<char>
{
    line_reader() : std::ctype<char>(get_table()) {}

    static std::ctype_base::mask const* get_table()
    {
        static std::vector<std::ctype_base::mask> rc(table_size, std::ctype_base::mask());
        rc['\n'] = std::ctype_base::space;
        return &rc[0];
    }
};

// in your conditional

else if (number > 0 && number <= 9) // no sense in checking larger numbers unless you convert the base
{
    std::string number_string = std::to_string(number);
    line_reader myReader;
    file.imbue(std::locale(std::locale(), myReader));
    count = std::count_if(std::istream_iterator<std::string>(file), std::istream_iterator<std::string>(), [&](const string& s)
    {
        return s[0] == number_string[0];
    });
}

First, there are a couple of problems with your example code. In C++, the EOF-bit is only set after you read something past the end of the file. This means that you will always read one junk line with your code. Instead, you should check if the data you read is actually valid before processing it. (See Why is iostream::eof inside a loop condition considered wrong? )

Also, you should be using std::getline to read the whole line, and not only to the next white space character.

Now on to your actual problem. If you know that number is always less than 10, you can use this trick:

char digit = '0' + number

This works because the numeric value of each digit character is always one greater than the previous. So for example the numeric value of the '1' digit character would be '0' + 1 , and so on.

With these changes, the final code is:

// Assert that the number is in the required range. 
assert(number < 10 && number >= 0 && "Expected a single digit!");
std::string line;
while(std::getline(file, line)) {
  if(line[0] == '0' + number) {
    ++count;
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM