Давайте посмотрим, не сможем ли мы туннелировать туннельное зрение. Вы хотите найти вещество с максимальной температурой кипения (как название, так и температуру), а затем вы хотите найти среднюю температуру кипения всех веществ. Чтобы сохранить название вещества с максимальной температурой кипения, а сама температура кипения будет принимать две переменные, такие как std::string
и double
, скажем namemax
и max
.
Вам также необходимо вычислить среднюю температуру кипения. Для вычисления среднего вам понадобится double
для хранения sum
, а затем целочисленное значение для хранения прочитанного числа точек кипения. (скажем, size_t cnt = 0;
)
Затем необходимо прочитать каждую name
и boiling
точку (которые должны быть std::string
и double
соответственно). Когда вы читаете цикл name
и boiling
, в вашем цикле вы хотите сравнить, если boiling > max
, и если да, обновите max = boiling;
и namemax = name;
, чтобы зафиксировать вещество и точку кипения как новый макс. Вы обновляете счетчик cnt
для каждой пары name
и boiling
read.
Когда ваша петля выходит, у вас есть namemax
и max
, содержащие вещество с самой высокой температурой кипения, поэтомувсе, что остается, - это вычислить среднюю температуру кипения как sum / cnt
.
. Чтобы собрать это вместе, начните с объявления ваших переменных и открытия вашего файла, например,
#include <iostream>
#include <fstream>
#include <string>
int main (int argc, char **argv) {
if (argc < 2) {
std::cerr << "error: insufficient arguments\n"
<< "usage: " << argv[0] << " filename\n";
return 1;
}
double boiling, sum = 0, max = 0;
size_t cnt = 0;
std::string name, namemax;
std::ifstream f(argv[1]);
Теперь цикл читает name
и boiling
с каждой строки. Примечание: как вы управляете циклом чтения, основываясь на успешном чтении и name
и boiling
, например,
while (f >> name && f >> boiling) {
sum += boiling; /* update sum with boiling */
if (boiling > max) { /* is boiling > max?, if so */
max = boiling; /* update max */
namemax = name; /* update namenax */
}
cnt++; /* increment counter */
}
Теперь все, что остаетсявычисление среднего значения и вывод результатов (что вы можете сделать все сразу):
std::cout << "average boiling pt. of " << cnt << " substances\n "
<< sum / cnt
<< "\n\nsubstance with max boiling point\n " << namemax
<< " (" << max << ")\n";
}
Готово! В целом, вы можете сделать:
#include <iostream>
#include <fstream>
#include <string>
int main (int argc, char **argv) {
if (argc < 2) {
std::cerr << "error: insufficient arguments\n"
<< "usage: " << argv[0] << " filename\n";
return 1;
}
double boiling, sum = 0, max = 0;
size_t cnt = 0;
std::string name, namemax;
std::ifstream f(argv[1]);
while (f >> name && f >> boiling) {
sum += boiling;
if (boiling > max) {
max = boiling;
namemax = name;
}
cnt++;
}
std::cout << "average boiling pt. of " << cnt << " substances\n "
<< sum / cnt
<< "\n\nsubstance with max boiling point\n " << namemax
<< " (" << max << ")\n";
}
Пример использования / Вывод
$ ./bin/boilingpt dat/boiling.txt
average boiling pt. of 24 substances
108.583
substance with max boiling point
Tar (300)
Добавление вывода каждой строки
Для каждого комментария вам также необходимо вывести каждое из значений, считанных из файла. Вы можете сделать это в начале цикла и просто вывести значения. Но давайте познакомим вас с std::setw()
, который позволяет вам установить ширину следующего вывода (name
), чтобы при выводе boiling
они были в хорошем столбце и не перемещались назад и вперед. Чтобы использовать std::setw()
, вы просто указываете ширину, например, std::setw(12)
будет работать в вашем случае. Функция std::setw()
находится в заголовке <iomanip>
, поэтому добавьте #include <iomanip>
вверху.
Когда вы используете std::setw()
, вы также хотите убедиться, что текст left-justified
, поэтому мы также будемвключите std::left
в вывод. Чтобы вывести каждую строку хорошим способом, вы можете изменить приведенный выше код на:
#include <iomanip>
...
std::cout << "substances and boiling points:\n"; /* output heading */
while (f >> name && f >> boiling) { /* read name/boiling pt */
std::cout << " " << std::setw(12) << std::left
<< name << "\t" << boiling << '\n'; /* output */
sum += boiling; /* add boiling to sum */
if (boiling > max) { /* is boiling > max, if so */
max = boiling; /* update max with boiling */
namemax = name; /* update namemax with name */
}
cnt++; /* increment counter */
}
std::cout << "\naverage boiling pt. of " << cnt << " substances\n "
<< sum / cnt
<< "\n\nsubstance with max boiling point\n " << namemax
<< " (" << max << ")\n";
( note: Я также включил итоговую строку вывода, потому что я добавил '\n'
вначало, чтобы оно было отделено от вашего списка пустой строкой)
Пример использования / Вывод
$ ./bin/boilingpt dat/boiling.txt
substances and boiling points:
Acetaldehyde 20.8
Acetone 50.5
Acetylene -84
Ammonia -35.5
Aniline 184.4
Benzene 80.4
Chloroform 62.2
Ethane -88
Ether 35
Furfurol 161.7
Glycerin 290
Glycerine 290
Naphthalene 218
Nitrobenzene 210.9
Petrol 95
Petroleum 210
Phenol 182
Propane -43
Propylene -47.7
Tar 300
Toluene 110.6
Turpentine 160
Water 100
Xylene 142.7
average boiling pt. of 24 substances
108.583
substance with max boiling point
Tar (300)
Если вы не использовали std::left
послеиспользуя std::setw(12)
, названия веществ будут выровнены по правому краю (опять же, не плохо), например,
$ ./bin/boilingpt dat/boiling.txt
substances and boiling points:
Acetaldehyde 20.8
Acetone 50.5
Acetylene -84
Ammonia -35.5
Aniline 184.4
Benzene 80.4
Chloroform 62.2
Ethane -88
Ether 35
Furfurol 161.7
Glycerin 290
Glycerine 290
Naphthalene 218
Nitrobenzene 210.9
Petrol 95
Petroleum 210
Phenol 182
Propane -43
Propylene -47.7
Tar 300
Toluene 110.6
Turpentine 160
Water 100
Xylene 142.7
average boiling pt. of 24 substances
108.583
substance with max boiling point
Tar (300)
Просмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы.