Использование данных из входного файла (строка и int) и использование в цикле - PullRequest
0 голосов
/ 05 октября 2019

Я должен создать программу, которая получает данные из входного файла и возвращает средние и максимальные значения (как точку кипения, так и связанную строку «вещество»). Данные из данного входного файла следующие:

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

Я знаю код для загрузки входных данных. Однако я не уверен, какие данные из него извлечь. Вот что я имею до этого момента:

int boiling, maximum=0,sum=0;
string substance;

///declare input stream variable
ifstream inData;

///open input file
inData.open("input.txt");

///Read the boiling temps
inData>>substance,boiling;

Вторая часть вопроса будет связана с использованием переменной 'string' из входного файла в цикле 'for', поскольку я не уверен, чтоиначе будет использоваться в качестве параметров для цикла. Я понятия не имею, как это сделать, и любое объяснение будет с благодарностью.

Я уверен, что у меня случай туннельного зрения и огромная проблема с моим синтаксисом, и я делаю что-то полностью и явно неправильноно я пока не могу обернуться вокруг этой проблемы. Если это поможет, мы находимся в точке обсуждения циклов for в классе.

**** РЕДАКТИРОВАТЬ ****

Таким образом:

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>

using namespace std;

int main()
{
///declare variables
double boiling, maximum=0,sum=0;
string substance, substancemax;

///declare input stream variable
ifstream inData;

///open input file
inData.open("input.txt");

///Read the boiling temps
inData>>substance>>boiling;

cout<<"Common Chemicals & Substances:"<<endl;
cout<<left<<setw(10)<<"Substance"
    <<right<<setw(13)<<"Boiling Point"<<endl;
cout<<"--------------------------------------"<<endl;
cout<<left<<setw(10)<<substance
    <<right<<setw(13)<<boiling<<endl;
    ///run a loop w/ 'if' to read the data and calculate the minimum
while(inData)
{
    ///read temperature
    inData>>boiling;
    sum=sum+boiling;

        ///compare boiling with current maximum w/ 'if'
    if (boiling>maximum)
    {
        substancemax=substance;   ///update max substance
    }
}
///Display the data to the screen
cout<<fixed<<showpoint<<setprecision(2);
cout<<"\nThe average boiling point is "<<sum/24.0<<endl;
cout<<"\nThe substance with the highest BP is "<<substancemax<<endl;
cout<<"\nThe highest boiling point is "<<maximum<<endl;

///close the input file
inData.close();


    return 0;
    }

Параметры оператора while все еще ускользают от меня, вероятно, в дополнение к другим проблемам.

******** FINAL EDIT ************

У меня есть программа, работающая с циклом 'for' (который, я полагаю, необходим, поскольку это глава, в которой мы находимся), за исключением того факта, что она выводит число в строке точки кипения. Я не уверен, откуда взялась эта цифра

Общие химические вещества и вещества:

Температура кипения вещества

                1.48738e+103

Ацетальдегид 20,8 Ацетон 50,5 Ацетилен -84 Аммиак -35,5 Анилин 184,4Бензол 80,4 Хлороформ 62,2 Этан -88 Эфир 35 Фурфурол 161,7 Глицерин 290 Глицерин 290 Нафталин 218 Нитробензол 210,9 Бензин 95 Нефть 210 Фенол 182 Пропан -43 Пропилен -47,7 Смола 300 Толуол 110,6 Скипидар 160 Вода 100 Ксилол 142,7

Средний *точка: 109,95

Вещество с самым высоким АД - смола

Самая высокая точка кипения - 300,00

. Моя кодировка следующая:

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>

using namespace std;

int main()
{
///declare variables
double boiling, maximum=0,sum=0,counter=0;
string substance, substancemax;

///declare input stream variable
ifstream inData;

///open input file
inData.open("input.txt");

///Label for file
cout<<"Common Chemicals & Substances:"<<endl;
cout<<left<<setw(20)<<"Substance"
<<"Boiling Point"<<endl;
cout<<"--------------------------------------"<<endl;

    ///run a loop w/ 'if' to read the data and calculate the minimum
for(counter=0;counter<=24;counter++)
{
cout<<left<<setw(20)<<substance
    <<left<<boiling<<endl;

    ///read temperature
    inData>>substance>>boiling;
    sum=sum+boiling;

        ///compare boiling with current maximum w/ 'if'
    if (boiling>maximum)
    {
        maximum = boiling;          ///update max boiling temp
        substancemax=substance;   ///update max substance
    }
}
///Display the data to the screen
cout<<fixed<<showpoint<<setprecision(2);
cout<<"\nThe average boiling point is "<<sum/counter<<endl;
cout<<"\nThe substance with the highest BP is "<<substancemax<<endl;
cout<<"\nThe highest boiling point is "<<maximum<<endl;

///close the input file
inData.close();

    return 0;
    }

Я не уверен, откуда этот вывод "1.48738e + 103" или как его устранить!

1 Ответ

0 голосов
/ 05 октября 2019

Давайте посмотрим, не сможем ли мы туннелировать туннельное зрение. Вы хотите найти вещество с максимальной температурой кипения (как название, так и температуру), а затем вы хотите найти среднюю температуру кипения всех веществ. Чтобы сохранить название вещества с максимальной температурой кипения, а сама температура кипения будет принимать две переменные, такие как 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)

Просмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...