-1

У меня есть несколько векторов. Есть обработка их элементов. Суть в том, что я должен обработать элементы и записать их в файл. Так и делаю, но я получаю какой-то мусор. Если точнее, то я получаю то, что должен получить, но вместе с этим, получаю и мусор.

Привожу примеры.

У меня есть два файла. 1.txt & 2.txt

Содержимое 1.txt:

4.3 2.1 5.3 20.4 1.1 200.5

2.txt - это файл, в который я постоянно загружаю результат обработки.

Пример 1. Добавил в конец вектора X ещё один элемент - 14.3

Ожидал: 4.3 2.1 5.3 20.4 1.1 200.5 14.3

Записалось: 4.3 2.1 5.3 20.4 1.1 200.5 14.3 /20.4 /Y.

Пример 2. Присвоить элементам последовательности Y значения X

Ожидал: 4.3 /2.1 /5.3 /20.4 /1.1 /200.5 /14.3

Записалось: 4.3 /2.1 /5.3 /20.4 /1.1 /200.5 /14.3 /Y.

Пример 3. Найти положение элемента по его значению (искал 200.5)

Ожидал: Элемент найден перед 14.3

Записалось:

Элемент найден перед 14.3
00.5 /14.3 /Y.

Пример 5. Упорядочить первые пять элементов последовательности

Ожидал: 1.1 /2.1 /4.3 /5.3 /14.3 /200.5 /20.4

Записалось: 1.1 /2.1 /4.3 /5.3 /14.3 /200.5 /20.4 /Y.

Пример 6. С первой последовательности удалить последние 3 элемента

Ожидал: 4.3 2.1 5.3

Записалось:

4.3
 2.1
 5.3
  /14.3 /200.5 /20.4 /Y.

Я подозреваю, что неправильно организовал вывод. Но как его организовать правильно? Можно ли сделать одну правильно работающую функцию, которую можно бы было вызывать, чтобы не дублировать по 150 раз один и тот же код? Опять-таки, ума не приложу, как это сделать.

Непосредственно код:

#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
using namespace std;

void show_vector(vector<float>& vec);

int main()
{
    setlocale(0, "");
    cout << " 1) создал пустую последовательность Х\n";
    vector<float> X;

    cout << " 2) заполнил Х из файла 1.txt\n";
    ifstream fin;
    fin.open("1.txt");
    if (!fin) cout << "\nНе могу открыть файл 1.txt для чтения.\n";
    int counter = 0;
    while (!fin.eof()) {
        X.resize(counter + 1);
        fin >> X[counter];
        counter++;
    }
    fin.close();

    cout << " 3.1) добавил ещё один элемент в конец вектора\n";
    X.push_back(14.3);

    cout << " 3.2) записал измененную последовательность в файл 2.txt\n";
    fstream fout;
    fout.open("2.txt");
    if (!fout) cout << "\nНе могу открыть или создать файл 2.txt для записи.\n";
    for (size_t i = 0; i < X.size(); ++i) {
        fout << X[i] << " ";
    }
    fout.close();
    system("pause");

    cout << " 4) создать вторую пустую последовательность\n";
    vector<float> Y;

    cout << " 5.1) присвоил элементам второй последовательности значения первой\n";
    Y.assign(begin(X), end(X));

    cout << " 5.2) записать вторую последовательность в файл 2.txt\n";
    fout.open("2.txt");
    if (!fout) cout << "\nНе могу открыть или создать файл 2.txt для записи.\n";
    for (size_t i = 0; i < Y.size(); ++i) {
        fout << Y[i] << " /";
    }
    fout.close();
    system("pause");

    cout << " 6) найти во второй последовательности позицию элемента, значение которого вводится с клавиатуры результат записать в файл 2.\n";
    fout.open("2.txt");
    if (!fout) cout << "\nНе могу открыть или создать файл 2.txt для записи.\n";
    float x;
    cout << "Определите значение, позицию которого Вы хотите найти -->>  "; cin >> x;
    vector<float>::iterator i = find(Y.begin(), Y.end(), x);
    if (i == Y.end()) // если элемент не найден, то find вернет Y.end()
        fout << "Элемент не найден в последовательности Y.\n";
    else {
        fout << "Элемент найден";
        if (i == Y.begin())   cout << " - это первый элемент\n";
        else fout << " перед " << *++i << endl;
    }
    fout.close();
    system("pause");

    cout << " 7) упорядочить первые пять элементов второй последовательности и записать в 2.txt\n";
    partial_sort(Y.begin(), Y.begin()+5, Y.end());
    fout.open("2.txt");
    if (!fout) cout << "\nНе могу открыть или создать файл 2.txt для записи.\n";
    for (size_t i = 0; i < Y.size(); ++i) {
        fout << Y[i] << " /";
    }
    fout.close();
    system("pause");

    cout << " 8) с первой последовательности удалить последние 3 элемента. Записать последовательность в 2.txt\n";
    // sort(data.begin() + m - n), data.end()); - аналог. m - начало, n - конец
    for (int i = 0; i <= 3 && !X.empty(); ++i)
        X.pop_back();

    fout.open("2.txt");
    if (!fout) cout << "\nНе могу открыть или создать файл 2.txt для записи.\n";
    for (auto f : X) { fout << f << endl << " "; }
    fout.close();
    system("pause");

    cout << " 9) обменять содержимое первой и второй последовательности, результат вывести на экран с помощью итераторов\n";
    cout << "\nДо обмена\n" << "X -->> ";
    show_vector(X);
    cout << "\nY -->> ";
    show_vector(Y);

    X.swap(Y);
    cout << "\nПосле обмена\n" << "X -->> ";
    show_vector(X);
    cout << "\nY -->> ";
    show_vector(Y);

    cout << "\n\n 10) вычислить сумму и среднее арифметическое первой последовательности\n";
    float sum(0), avreage(0); counter = 0;
    for(size_t i = 0; i < X.size(); i++) {
        sum += X[i];
        counter++;
    }
    avreage = sum / counter;
    cout << endl << endl << "X -->> "; show_vector(X);
    cout << "\nСумма последовательности X -->> " << sum << ", среднее арифметическое последовательности X -->> " << avreage << endl;

    cout << "\n\n 11) ИЗ: поделить каждый положительный элемент вектора на минимальный элемент\n";
    cout << "\n\nX -->> ";
    show_vector(X);
    float MinElement = *min_element(X.begin(), X.end()); cout << "\nМинимальный элемент в X -->> " << MinElement << endl;
    for(size_t i = 0; i < X.size(); i++) {
        if (X[i] > 0) X[i] /= MinElement;
    }
    cout << "X -->> ";
    show_vector(X);

    cout << "\n\nY -->> ";
    show_vector(Y);
    MinElement = *min_element(Y.begin(), Y.end()); cout << "\nМинимальный элемент в Y -->> " << MinElement << endl;
    for (size_t i = 0; i < Y.size(); i++) {
        if (Y[i] > 0) Y[i] /= MinElement;
    }
    cout << "Y -->> ";
    show_vector(Y);

    return 0;
}

void show_vector(vector<float>& vec) {
    for(vector<float>::iterator it = vec.begin(); it != vec.end(); ++it)
        cout << *it << " ";
}

Вывод во всех случаях организовываю по такому принципу:

fsteram fout;
....
fout.open("2.txt");
    if (!fout) cout << "\nНе могу открыть или создать файл 2.txt для записи.\n";
    for (size_t i = 0; i < X.size(); ++i) {
        fout << X[i] << " ";
    }
    fout.close();
dbUser11
  • 278

1 Answers1

2

Вы попали на типичную проблему непонимания eof. eof не проверяет "будет ли конец файла". Он проверяет "а не был ли конец файла при последнем чтении". Поэтому, читается лишнее число

вместо вот этого страшного

while (!fin.eof()) {
    X.resize(counter + 1);
    fin >> X[counter];
    counter++;
}

лучше написать так

float t;
while (fin >> t) {
    X.push_back(t);
}

и красивее, и проще.

KoVadim
  • 112,121
  • 6
  • 94
  • 160
  • Да, ошибку понял. Заменил свой код на Ваш. Только вывод остался таким же(

    Все равно не получаю того, чего ожидаю. Понять не могу, что работает не так

    – dbUser11 Apr 16 '20 at 14:36
  • Нашел ещё одну проблему. fstream заменил на ofstream - и все стало так, как я и ожидал) – dbUser11 Apr 16 '20 at 14:48
  • интересно. думаю там что то другое – KoVadim Apr 16 '20 at 15:17