C++温度计

mfpqipee  于 2023-02-26  发布在  其他
关注(0)|答案(2)|浏览(141)

我有一个C的学校作业,这是我第一次用C作业。我只做了Python,所以我有点迷路。我几乎是一个初学者的编码,所以我会感谢任何帮助。
作业是写一个程序来显示一个"温度计"。温度在一个数组中给出。正数显示为|*****(这是针对数字5的),负数为*****|(对于-5),如果值为0,则它只是|。如果缺少值,将有no_value,并且其输出将与之前的输出相同(如果no_value之前的数字是4,则它是|****)。
在输出中,|应该表示0,因此他们正在创建一条线。
这是我的代码:

int main() {
    constexpr int no_value = -999;
    constexpr int temperatures[] { 10, 12, no_value, no_value, 20, 14, 6, -1, -5, 0, no_value, 1, -3 };
    int previous_value = 0;

    while (cin >> temperatures) {

        if (temperatures == no_value) {  //for no_value
            temperatures = previous_value;
        }
        else {
            previous_value = temperatures;
        }
        if (temperatures > 0) {   // for positive value
            cout << "|";
            for (int i = 0; i < temperatures; i++) {
                cout << "*";
            }
        }
        else if (temperatures < 0) {    //for negative value
            for (int i = 0; i < -temperatures; i++) {
                cout << "*";
            }
            cout << "|";
        }
        else {   //for value == 0
            cout << "|";
        }
        cout << endl;
    } 

    return 0;
}

有运算符错误,以及一些不兼容的操作数类型。它还告诉我,在第13行(在第一个if之后)表达式必须是可修改的左值。
我也不知道怎么让|每次都在同一个位置,我想用负数绝对值最大的那个来腾出空间,但是我不知道怎么写。
我很感激你的帮助和解释。

6vl6ewon

6vl6ewon1#

表达式while (cin >> temperatures)将不起作用。首先,temperaturesconstexpr,所以它不能被修改。其次,因为没有operator>>可以读取整个数组的值。就此而言,您的指令中根本没有说明您需要读取用户的输入,因此您甚至不应该在此程序中使用cin
此外,所有的iffor都试图将整个数组与单个值进行比较,这也是行不通的。
我认为你需要了解数组的实际含义,以及你能用数组做什么,不能用数组做什么。
你的程序试图把数组作为一个整体来处理的每件事,看起来都应该是对数组的 * 每个值 * 来处理。
试试这样的方法:

#include <iostream>
using namespace std;

int main() {
    constexpr int no_value = -999;
    constexpr int temperatures[] { 10, 12, no_value, no_value, 20, 14, 6, -1, -5, 0, no_value, 1, -3 };
    int previous_value = 0;

    for (int temperature : temperatures) {

        if (temperature == no_value) {  //for no_value
            temperature = previous_value;
        }
        else {
            previous_value = temperature;
        }

        if (temperature > 0) {   // for positive value
            cout << '|';
            for (int i = 0; i < temperature; ++i) {
                cout << '*';
            }
        }
        else if (temperature < 0) {    //for negative value
            temperature = -temperature;
            for (int i = 0; i < temperature; ++i) {
                cout << '*';
            }
            cout << '|';
        }
        else {   //for value == 0
            cout << '|';
        }
        cout << '\n';
    } 

    return 0;
}

输出:

|**********
|************
|************
|************
|********************
|**************
|******
*|
*****|
|
|
|*
***|

Online Demo
然后,要排列|,只需根据需要在|的每一侧添加适量的空格即可,例如:

#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;

int main() {
    constexpr int no_value = -999;
    constexpr int temperatures[] { 10, 12, no_value, no_value, 20, 14, 6, -1, -5, 0, no_value, 1, -3 };
    int previous_value = 0;
    int max_value = 0;

    for (int temperature : temperatures) {
        if (temperature != no_value) {
            max_value = max(max_value, abs(temperature));
        }
    }

    for (int temperature : temperatures) {

        if (temperature == no_value) {
            temperature = previous_value;
        }
        else {
            previous_value = temperature;
        }

        if (temperature > 0) {   // for positive value
            for (int i = 0; i < max_value; ++i) {
                cout << ' ';
            }
            cout << '|';
            for (int i = 0; i < temperature; ++i) {
                cout << '*';
            }
            for (int i = temperature; i < max_value; ++i) {
                cout << ' ';
            }
        }
        else if (temperature < 0) {    //for negative value
            temperature = abs(temperature);
            for(int i = max_value; i > temperature; --i) {
                cout << ' ';
            }
            for (int i = 0; i < temperature; ++i) {
                cout << '*';
            }
            cout << '|';
            for (int i = 0; i < max_value; ++i) {
                cout << ' ';
            }
        }
        else {   //for value == 0
            for(int i = 0; i < max_value; ++i) {
                cout << ' ';
            }
            cout << '|';
            for(int i = 0; i < max_value; ++i) {
                cout << ' ';
            }
        }
        cout << '\n';
    } 

    return 0;
}

输出:

|**********          
                    |************        
                    |************        
                    |************        
                    |********************
                    |**************      
                    |******              
                   *|                    
               *****|                    
                    |                    
                    |                    
                    |*                   
                 ***|

Online Demo
通过使用std::setw()std::setfill() I/O操纵器替换手动打印循环,可以进一步改进,例如:

#include <iostream>
#include <iomanip>
#include <cmath>
#include <algorithm>
using namespace std;

int main() {
    constexpr int no_value = -999;
    constexpr int temperatures[] { 10, 12, no_value, no_value, 20, 14, 6, -1, -5, 0, no_value, 1, -3 };
    int previous_value = 0;
    int max_value = 0;

    for (int temperature : temperatures) {
        if (temperature != no_value) {
            max_value = max(max_value, abs(temperature));
        }
    }

    for (int temperature : temperatures) {

        if (temperature == no_value) {
            temperature = previous_value;
        }
        else {
            previous_value = temperature;
        }

        if (temperature > 0) {   // for positive value
            cout << setw(max_value) << setfill(' ') << ' ';
            cout << '|';
            cout << setw(temperature) << setfill('*') << '*';
            if (temperature < max_value) {
                cout << setw(max_value-temperature) << setfill(' ') << ' ';
            }
        }
        else if (temperature < 0) {    //for negative value
            temperature = abs(temperature);
            if (temperature < max_value) {
                cout << setw(max_value-temperature) << setfill(' ') << ' ';
            }
            cout << setw(temperature) << setfill('*') << '*';
            cout << '|';
            cout << setw(max_value) << setfill(' ') << ' ';
        }
        else {   //for value == 0
            cout << setw(max_value) << setfill(' ') << ' ';
            cout << '|';
            cout << setw(max_value) << setfill(' ') << ' ';
        }
        cout << '\n';
    } 

    return 0;
}

输出:

|**********          
                    |************        
                    |************        
                    |************        
                    |********************
                    |**************      
                    |******              
                   *|                    
               *****|                    
                    |                    
                    |                    
                    |*                   
                 ***|

Online Demo

4xrmg8kj

4xrmg8kj2#

首先看一下错误:

|     while (cin >> temperatures) {

error: no match for 'operator>>' (operand types are 'std::istream' {aka 'std::basic_istream<char>'} and 'const int [13]')
您试图将std::cin中的值直接读入int数组,但没有operator>>重载支持此操作。

|         if (temperatures == no_value) {  //for no_value
|             ~~~~~~~~~~~~~^~~~~~~~~~~

error: ISO C++ forbids comparison between pointer and integer
temperatures衰减为指向数组中第一个元素(const int*)的指针。您不能比较const int*int

|             temperatures = previous_value;

error: assignment of read-only variable 'temperatures'
temperatures被声明为常量,因此您无法对其进行更改。即使它 * 曾经 * 不是const,您也可以对其进行赋值。数组没有赋值运算符,previous_value甚至不是数组。

|             previous_value = temperatures;
|                              ^~~~~~~~~~~~
|                              |
|                              const int*

error: invalid conversion from 'const int*' to 'int'
也不支持将const int*(同样,temperatures衰减为指向数组中第一个元素的指针)赋给int

|         if (temperatures > 0) {   // for positive value
|             ~~~~~~~~~~~~~^~~

error: ordered comparison of pointer with integer zero ('const int*' and 'int')(检查负值时发生相同错误)
您正在尝试将const int*int进行比较。不支持。

|             for (int i = 0; i < temperatures; i++) {
|                             ~~^~~~~~~~~~~~~~

x1米20英寸1x
......这里也有类似的问题。

|             for (int i = 0; i < -temperatures; i++) {
|                                  ^~~~~~~~~~~~

error: wrong type argument to unary minus
否定一个const int*也不起作用。
我建议您创建一个helper函数,用于创建表示不同温度计的std::string,为了正确显示它,您首先需要找到数组中的最低温度,以防所有温度都为正,而您仍然希望显示零线,找到最低温度后,helper函数如下所示:std::string的第一个参数是一个计数,第二个参数是你想要的字符,所以你可以用std::string(5, '*')创建一个5个星号的字符串,例如:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>

std::string get_thermometer(int temp, int min) {
    // how much to fill before the 0-line:
    std::string result(std::min(temp, 0) - min, ' ');

    // if negative temp, add asterisks:    
    if(temp < 0) result += std::string(-temp, '*');
    
    result += '|'; // 0-line
    
    // if positive temp, add asterisks:
    if(temp > 0) result += std::string(temp, '*');

    return result;
}

找到最小温度可以用标准的std::min_element算法来完成,你也可以用std::minmax_element同时找到最小和最大元素,我用它来显示数组中的温度范围,两个算法都返回 iterators,它是一个指向被找到元素的指针(或者是一个实际的指针),通过解引用(*iterator)一个迭代器(指针),你会得到一个对迭代器所指向的实际值的引用。

int main() {
    constexpr int no_value = -999;
    constexpr int temperatures[]{10, 12, no_value, no_value, 20, 14, 6,
                                 -1, -5, 0,        no_value, 1,  -3};

    // get iterators to the min and max values (skipping the no_value elements):
    auto [minit, maxit] = std::minmax_element(
        std::begin(temperatures), std::end(temperatures),
        [](int lhs, int rhs) { return lhs != no_value && lhs < rhs; });

    // make sure 0 is represented on the thermometer even if only negative or
    // only positive temperatures are present in the array:
    int min = std::min(*minit, 0);
    int max = std::max(*maxit, 0);

    std::cout << "temperature range: [" << *minit << ", " << *maxit << "]\n";
    std::cout << "thermometer range: [" << min << ", " << max << "]\n";

    for (std::string tempstr; int temp : temperatures) {
        if (temp != no_value) tempstr = get_thermometer(temp, min);
        // else keep the old tempstr

        std::cout << tempstr << '\n';
    }
}

输出:

temperature range: [-5, 20]
thermometer range: [-5, 20]
     |**********
     |************
     |************
     |************
     |********************
     |**************
     |******
    *|
*****|
     |
     |
     |*
  ***|

Demo

相关问题