【问题标题】:Getting different results using "cin" for Drill #7 in Chapter 4 of Programming: Principles and Practice using C++ (Stroustrup)在编程的第 4 章中使用“cin”为第 7 章钻取不同的结果:使用 C++ 的原则和实践 (Stroustrup)
【发布时间】:2015-04-10 12:28:42
【问题描述】:

我正忙于阅读《编程:使用 C++ 的原则和实践》(Stroustrup)的第二版,在读取值之间是否有空格,然后再次显示时遇到了问题。

能否请您指出正确的方向,以便我找出结果不同的原因?

代码编译正常:c++ -std=c++11 -o 7 7.cpp

输入测试结果:

  • 10公里(工程)
  • 10 公里(工程)
  • 10 厘米(作品)
  • 10 厘米(不工作)

这是代码以及一些具有不同结果的测试输入/输出。

#include "../../std_lib_facilities.h"

/*
Add a unit to each double entered; that is, enter values such as 10cm, 2.5in, 5ft, or 3.33m.
Accept the four units: cm, m, in, ft. Assume conversion factors 1m == 100cm, 1in ==
2.54cm, 1ft == 12in. Read the unit indicator into a string. You may consider 12 m (with a
space between the number and the unit) equivalent to 12m (without a space).
*/

int main()
{
    double value = 0.0;
    string unit = "";
    double largest_so_far = 0.0;
    double smallest_so_far = 0.0;
    char resp = 'y';


    // Conversions
    constexpr double m = 100.0;     // 1m = 100cm
    constexpr double in = 2.5;      // 1in = 2.54cm
    constexpr double ft = 12.0;     // 1ft = 12in

    cout << "\n\n\nGive me a floating point value and a unit (ex. 10 cm):   ";
    cin >> value >> unit;

    largest_so_far = value;
    smallest_so_far = value;
    cout << "\nYou gave me the following: " << value << " " << unit << '\n';
    cout << "Thank you.  The largest and smallest so far is now " << value << "\n\n";

    while (resp != '|') {
        cout << "\n\n\nGive me a floating point value:   ";
        cin >> value;

        if (value > largest_so_far)
        {
            largest_so_far = value;
            cout << "You gave me " << largest_so_far << ", the largest so far\n";
        }
        if (value < smallest_so_far) 
        {
            smallest_so_far = value;
            cout << "You gave me " << smallest_so_far << ", the smallest so far\n";
        }


        cout << "Another one? ('|' to stop, any other char for one more) :  ";
        cin >> resp;
    }
}

导致失败的值(例如“10cm”)最终会在程序中进入一个奇怪的循环。

输出:给我一个浮点值:另一个? ('|' 停止,任何 另一个字符):给我一个浮点值:另一个 一? ('|' 停止,任何其他字符):给我一个浮动 点值:另一个? ('|' 停止,任何其他字符为一个):

然后我必须按 CTRL-C 退出。

一个更小的测试,感谢 MSalters...

#include "../../std_lib_facilities.h"

/*
    Add a unit to each double entered; that is, enter values such as 10cm, 2.5in, 5ft, or 3.33m.
    Accept the four units: cm, m, in, ft. Assume conversion factors 1m == 100cm, 1in ==
    2.54cm, 1ft == 12in. Read the unit indicator into a string. You may consider 12 m (with a
    space between the number and the unit) equivalent to 12m (without a space).
*/

int main()
{
    double value = 0.0;
    string unit = "";

    cout << "\n\n\nGive me a floating point value and a unit (ex. 10 cm):   ";
    if (cin >> value >> unit)
        cout << "Success, got 2 values\n";
    else
        cout << "Failure!\n";

    cout << "\nYou gave me the following: " << value << " " << unit << '\n';

}

~/dev/cpp/ch4/drill/./test 给我一个浮点值和一个单位(例如 10 厘米):10 厘米 失败! 你给了我以下内容:0

~/dev/cpp/ch4/drill/./test 给我一个浮点值和一个单位(例如 10 厘米):10km 成功,得到 2 个值 你给了我以下:10公里

~/dev/cpp/ch4/drill/./test 给我一个浮点值和一个单位(例如 10 厘米):10 公里 成功,得到 2 个值 你给了我以下:10公里

~/dev/cpp/ch4/drill/./test 给我一个浮点值和一个单位(例如 10 厘米):10 厘米 成功,得到 2 个值 你给了我以下:10厘米

为什么只有以小于“k”的字符开头的字符串才会失败?

【问题讨论】:

  • 请阅读关于提出好问题的规则。当您说“不起作用”时,什么不起作用以及它到底是如何失败的?
  • 我发现如果我使用“a”和“j”之间的字符串,它会失败,但如果单位的字符以“k”或更高版本开头,它就可以正常工作。导致失败的值(例如“10cm”)最终会在程序中进入一个奇怪的循环。输出:给我一个浮点值:另一个? ('|' 停止,任何其他字符为更多):给我一个浮点值:另一个? ('|' 停止,任何其他字符为更多):给我一个浮点值:另一个? ('|' 停止,任何其他字符为一个):然后我必须按 CTRL-C 退出。
  • 您可以在 StackOverflow 上编辑您的问题。我已将您评论的相关部分添加到您的问题中。您仍然可以添加其他相关详细信息。
  • 您的结果没有任何意义,10cm 没有理由不能被 cin &gt;&gt; value &gt;&gt; unit 正确读取(当我下载 std_lib_facilities.h 标头并尝试您的代码时,它工作正常)。

标签: c++ c++11


【解决方案1】:

我也遇到了这个错误,所以我问了这个问题的重复版本,希望得到答案。这是我的发现:

  • 这似乎是 clang 使用的一个标准库中的一个实际错误。这个确切错误的错误报告是linked here

  • 该错误似乎与转换说明符有关,这可以解释为什么只有一些字母而不是其他字母受到它的影响。可能是转换说明符的字母(例如,浮点数的 10.0f)被库以不同方式解析,在这种情况下,它会影响 cin 正确拆分双精度和字符串的能力。

  • 2年过去了,bug还没解决……

我使用 -stdlib=libstdc++ 重新编译了我自己的类似问题代码,这是一个与默认 libc++ 库不同的库。它现在可以正常工作,尽管字母 E 仍然不能接受,因为它表示指数。

非常感谢 stackoverflow 用户 Petesh 找到了这个问题的真正答案。

【讨论】:

    【解决方案2】:

    输入操作可能会失败。很容易测试:if(cin) /* All went right so far */if (!cin) /* something went wrong */

    现在您的问题是,当出现问题时,您必须清除故障状态才能接受新输入:cin.clear()。此外,在您的代码中,您应该在尝试使用valueunit 之前测试提取是否有效。

    专业提示:您可以将其结合起来。

      if (cin >> value >> unit)
      {
         // Success - value and unit now hold the users input
      }
      else
      {
        // uh oh, that's not good
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多