Reputation: 13
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? e.g. '1' == '1'
therefore count++
Upvotes: 0
Views: 1096
Reputation: 15872
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];
});
}
Upvotes: 0
Reputation: 11963
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;
}
}
Upvotes: 0
Reputation: 171127
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) {
//...
}
Upvotes: 0