Итак, у меня есть текстовый файл, который выглядит так:
5
4
9
-3
0
2
first int показывает, сколько их int нужно упорядочить в порядке возрастания, поэтому вывод выглядит следующим образом:
-3
0
2
4
9
Я пытаюсь сделать это без каких-либо дополнительных библиотек и просто использую
#include <iostream>
#include <fstream>
Пока мой код читает первый int, но когда он хочет прочитать остальные, он не работает. Я все еще застрял в части чтения.
int main()
{
ifstream input;
int a,N,i,j;
int temp;
// Open the file.
input.open("test.txt");
if (!input) {
cerr << "Could not open the file - '"<< endl;
return EXIT_FAILURE;
}
// Read the numbers of int from the file
cout<<"Input fail data"<<endl;
input>>N;
cout<<"integers: "<<N<<endl;
int data[N];
//
for(i = 0; i << N; i++){
input>>data[i];
P.S. Должны ли остальные целые числа быть в массиве или в связанном списке?
i << N
сдвигает влево i вместо сравнения с N. Сдвиг влево 0 равен 0 ложно. Таким образом, цикл for никогда не выполняется.
Пожалуйста, используйте тему вашего вопроса в заголовке, а не тему общей задачи, поставленной перед вами. Вы даже не стали ничего разбирать.
Итак, я попробовал ваш код, и он заработал после некоторых незначительных изменений, которые касаются только возможности компиляции, но не фактического подхода к чтению данных. Код считает, что ваше ограничение включает только iostream
и fstream
.
#include <iostream>
#include <fstream>
int main()
{
std::ifstream input("test.txt");
if (!input) {
std::cerr << "Could not open the file - '"<< std::endl;
return -1;
}
// Read the numbers of int from the file
int N;
input >> N;
std::cout << "reading " << N << " integers: " << std::endl;
int* data = new int[N];
for(int i = 0; i < N; i++){
input >> data[i];
std::cout << data[i] << std::endl;
}
delete[] data;
}
Возможно, в вашем коде что-то не так, кроме части чтение.
Я даже не начал то, что после части чтения. Но, как я уже сказал выше, я пытаюсь сделать это только с помощью #iostream и #fstream.
Я только что обновил ответ, чтобы избежать std::vector
. Теперь он динамически выделяет память с помощью оператора new
.
Когда вы используете new[]
, вы должны использовать delete[]
.
Вы правы, delete[]
вызывает деструктор каждого объекта массива, а delete
вызывает деструктор только для первого объекта. Хотя в данном конкретном случае это не имеет значения, так как это только целые числа. Спасибо за подсказку ;)
Две вещи, которые не очень-то-С++: 1) Используйте правильный RAII, где это возможно; std::ifstream input( "test.txt" )
было бы лучше, чем объявлять первое, инициализируя второе. 2) Используйте ли нет массивы new
и / или C, если это абсолютно необходимо. std::vector
существует по уважительной причине очень и должен быть предпочтительным практически во всех возможных случаях. (Если бы это было глубоко внутри приложения, и ваш цикл for
срабатывал, ваш delete[]
никогда не будет вызван, и ваш ресурс просочится.)
@DevSolar 1) Ты прав, я это изменю. 2) Вопрос заключался в том, чтобы явно избегать любых других #includes (включая вектор), так что это не вариант в отношении вопроса. Кроме того, я согласен с вами и в этом случае.
@Дж.П.С. {вздыхает} Пропустил это. Почему инструкторы навязывают своим ученикам именно это, а не обучение языку effin '?
Если вам не разрешено использовать определенные включения, вы можете запустить его с любым включением, которое вам нравится, и использовать обработанный вывод препроцессора без включений в качестве вашего файла .cpp. ;-)
Стандартный C++ не поддерживает VLA:s (массивы переменной длины). Вместо этого используйте std::vector<int>
.
Пример:
#include <algorithm> // copy_n
#include <cerrno> // errno
#include <cstring> // strerror
#include <fstream>
#include <iostream>
#include <iterator> // istream_iterator
#include <vector> // vector instead of VLA
int main() {
std::ifstream input("test.txt");
if (!input) {
std::cerr << "Could not open the file: " << std::strerror(errno) << '\n';
return EXIT_FAILURE;
}
// Read the numbers of int from the file
int N;
if (!(input >> N && N > 0)) {
std::cerr << "invalid number of elements\n";
return EXIT_FAILURE;
}
std::vector<int> data(N); // instead of `int data[N];`
// copy ints from `input` to `data`:
std::copy_n(std::istream_iterator<int>(input), data.size(), data.begin());
// or:
// for(int& val : data) std::cin >> val;
std::cout << "integers: " << data.size() << '\n';
// sort them
std::sort(data.begin(), data.end());
for (int val : data) std::cout << val << '\n';
}
Если вы хотите сделать это без поддержки std::vector
и т. д., вы можете сами создать простой класс-контейнер.
Пример:
#include <fstream>
#include <iostream>
template <class T>
class arr {
public:
using value_type = T;
using const_iterator = const value_type*;
using iterator = value_type*;
using const_reference = const value_type&;
using reference = value_type&;
arr(size_t x) : data(new T[x]), len(x), capacity(x) {}
// copy ctor
arr(const arr& rhs) : arr(rhs.len) {
for (size_t i = 0; i < len; ++i) data[i] = rhs.data[i];
}
// move ctor
arr(arr&& rhs) noexcept : data(rhs.data), len(rhs.len), capacity(rhs.capacity) {
rhs.data = nullptr;
}
// copy assignment operator
arr& operator=(const arr& rhs) {
if (this == &rhs) return *this;
if (capacity < rhs.len) {
delete[]data;
data = new T[rhs.len];
capacity = rhs.len;
}
len = rhs.len;
for (size_t i = 0; i < len; ++i) data[i] = rhs.data[i];
return *this;
}
// move assignment operator:
arr& operator=(arr&& rhs) noexcept {
if (this == &rhs) return *this;
delete[] data;
data = rhs.data;
rhs.data = nullptr;
len = rhs.len;
capacity = rhs.capacity;
return *this;
}
// destructor
~arr() { delete[] data; }
size_t size() const { return len; }
const_reference operator[](size_t idx) const { return data[idx]; }
reference operator[](size_t idx) { return data[idx]; }
const_iterator cbegin() const { return data; }
const_iterator cend() const { return data + len; }
const_iterator begin() const { return cbegin(); }
const_iterator end() const { return cend(); }
iterator begin() { return data; }
iterator end() { return data + len; }
private:
T* data;
size_t len, capacity;
};
И его использование будет похоже на использование VLA:
int main() {
std::ifstream input("test.txt");
if (!input) {
std::cerr << "Could not open the file\n";
return EXIT_FAILURE;
}
// Read the numbers of int from the file
int N;
if (!(input >> N && N > 0)) {
std::cerr << "invalid number of elements\n";
return EXIT_FAILURE;
}
arr<int> data(N); // instead of `int data[N];`
for (int& val : data) std::cin >> val;
std::cout << "integers: " << N << '\n';
// implement your own sorting algorithm and use it here
for (int val : data) std::cout << val << '\n';
}
int data[N];
для постоянной времени без компиляции является нестандартным расширением C++. Вместо этого используйтеstd::vector<int>
...