【问题标题】:C++ passing integer parameter to function and converting to char for conditionalC ++将整数参数传递给函数并将条件转换为char
【发布时间】:2013-10-11 18:05:47
【问题描述】:

int number 是此代码所在函数的参数。 first_digit 是一个字符串,它已从 ifstream 文件中传递了第一个值

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;
            }

如果文件中的第一个数字与参数int number 的字符值匹配,我想要做的是count++。 AKA 我正在尝试计算第一个数字与number 匹配的行。 number 是从一个单独的函数传递的,该函数将发送数字 for(i=1;1<10;i++),因此我将以文件中第一个数字为 1、2、3 等的次数的总和结束

我正在努力解决的是条件!我如何将字符串 first_digit 的第一个索引位置与 int n 关联起来,因为它们具有相同的 char 值?例如'1' == '1' 因此count++

【问题讨论】:

  • 是否可以将char number 作为参数传递给代码来自的函数?毕竟,您想计算以给定字符而不是给定数字开头的行数(如果数字大于 9 会怎样?)

标签: c++ conditional


【解决方案1】:

数字字符的数值保证是递增和连续的。换句话说,我相信您正在寻找这个:

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

【讨论】:

  • 只要number <= 9 就可以工作。如果number 是一个很大的值(例如 1000),这将给出有趣的结果。
  • @ZacHowland 这永远不会是真的(在 8 位到字节的硬件上),因为算术是在 ints 中完成的,而 first_digit[0]char。我从问题中了解到0 <= number <= 9是函数的前提条件。
  • 我没有看到他在进入函数之前(也不是在函数内部)检查number 的任何地方,但如果是,那么就没有问题。如果不是,则结果将不理想(当int 降级为char 并且int 大于255 ...)
  • @ZacHowland 我的代码中没有“降级”。 '0' 将被提升为int,因为+ 的另一个操作数是int,然后first_digit[0] 将被提升为int,因为== 的另一个操作数是int .如果函数将0 <= number <= 9 声明为其前提条件(据我所知),那么调用代码有责任保证这一点,并且函数可以认为这是理所当然的。 “如果不满足先决条件,则行为未定义。”
  • "如果不满足前提条件,则行为未定义。" - 这是我的全部观点。我在他的问题中没有看到任何先决条件,而您的答案假定它们没有指定。
【解决方案2】:

只有当number 介于 0 和 9 之间时,您尝试执行的操作才会起作用。此外,如果 first_digitstring,则 first_digit[0]char,然后您正在尝试这样做与string 比较(这不起作用)。

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++;
        }
    }
}

或者,您也可以使用std::count_if 为您完成这一切,而不是编写自己的循环。它看起来类似于以下内容(注意:尚未调试):

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];
    });
}

【讨论】:

    【解决方案3】:

    首先,您的示例代码存在一些问题。在 C++ 中,EOF 位仅在您读取文件末尾之后的内容之后设置。这意味着您将始终使用您的代码阅读一个垃圾行。相反,您应该在处理之前检查您读取的数据是否确实有效。 (见Why is iostream::eof inside a loop condition considered wrong?

    此外,您应该使用std::getline 来读取整行,而不仅仅是下一个空格字符。

    现在谈谈你的实际问题。如果你知道这个数字总是小于 10,你可以使用这个技巧:

    char digit = '0' + number
    

    这是因为每个数字字符的数值总是比前一个大一。因此,例如'1' 数字字符的数值将为'0' + 1,依此类推。

    有了这些改动,最终的代码是:

    // 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;
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-23
      • 2012-07-26
      • 1970-01-01
      • 2021-04-13
      • 2013-10-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多