Реализовала односвязный список с помощью шаблона класса. В основной программе написала подпрограммы ввода и вывода в файл. При создании списка целых чисел все выводится корректно. Но когда создаю список символов последний элемент выводится дважды. В чем может быть ошибка?
List.h:
template <typename T>
class List {
public:
List();
~List();
bool IsEmpty();
void push_front(T data);
void push_middle(T data);
void push_back(T data);
void pop_front();
void pop_middle();
void pop_back();
void removeAt(int index);
T& get_first();
T& get_last();
T& get_middle();
void clear();
int GetSize() const { return Size; }
T& operator[](const int index) const ;
private:
template<typename U>
class Node
{
public:
Node * pNext;
U data;
Node(U data = U(), Node *pNext = nullptr)
{
this->data = data;
this->pNext = pNext;
}
};
int Size;
Node<T> *head;
};
List.cpp:
#include "List.h"
#include <iostream>
using namespace std;
template<typename T>
List<T>::List()
{
Size = 0;
head = nullptr;
}
template<typename T>
List<T>::~List(){
clear();
}
template<typename T>
bool List<T>::IsEmpty() {
return ( head == nullptr );
}
template<typename T>
void List<T>::pop_front(){
Node<T> *temp = head;
head = head->pNext;
delete temp;
Size--;
return;
}
template<typename T>
void List<T>::push_back(T data){
if (head == nullptr){
head = new Node<T>(data);
}
else{
Node<T> *current = this->head;
while (current->pNext != nullptr){
current = current->pNext;
}
current->pNext = new Node<T>(data);
}
Size++;
return;
}
template<typename T>
void List<T>::clear(){
while (Size){
pop_front();
}
return;
}
template<typename T>
T & List<T>::operator[](const int index) const
{
int counter = 0;
Node<T> *current = this->head;
while (current != nullptr)
{
if (counter == index)
{
return current->data;
}
current = current->pNext;
counter++;
}
}
template<typename T>
void List<T>::push_front(T data){
head = new Node<T>(data, head);
Size++;
return;
}
template<typename T>
void List<T>::push_middle(T data){
if (this->Size == 1){
push_front(data);
}
else{
Node<T> *previous = this->head;
for (int i = 0; i < this->Size/2 - 1; i++){
previous = previous->pNext;
}
auto *newNode = new Node<T>(data, previous->pNext);
previous->pNext = newNode;
Size++;
}
return;
}
template<typename T>
void List<T>::removeAt(int index){
if (index == 0){
pop_front();
}
else{
Node<T> *previous = this->head;
for (int i = 0; i < index - 1; i++){
previous = previous->pNext;
}
Node<T> *toDelete = previous->pNext;
previous->pNext = toDelete->pNext;
delete toDelete;
Size--;
}
return;;
}
template<typename T>
void List<T>::pop_middle(){
if (Size == 1){
pop_front();
}
else{
Node<T> *previous = this->head;
for (int i = 0; i < Size/2 - 1; i++){
previous = previous->pNext;
}
Node<T> *toDelete = previous->pNext;
previous->pNext = toDelete->pNext;
delete toDelete;
Size--;
}
return;
}
template<typename T>
void List<T>::pop_back(){
if (Size == 1){
pop_front();
}
else{
Node<T> *previous = this->head;
for (int i = 0; i < Size - 2; i++){
previous = previous->pNext;
}
Node<T> *toDelete = previous->pNext;
previous->pNext = toDelete->pNext;
delete toDelete;
Size--;
}
return;
}
template<typename T>
T &List<T>::get_first() {
return head->data;
}
template<typename T>
T &List<T>::get_last() {
if(Size==1){
get_first();
}
else {
Node<T> *previous = this->head;
for (int i = 0; i < Size - 1; i++) {
previous = previous->pNext;
}
return previous->data;
}
}
template<typename T>
T &List<T>::get_middle() {
if(Size==1){
get_first();
}
else {
Node<T> *previous = this->head;
for (int i = 0; i < Size/2; i++) {
previous = previous->pNext;
}
return previous->data;
}
}
Основная программа:
#include "List.h"
using namespace std;
template <typename T>
void InputList(List<T>& lst, char* fname){
fstream file;
file.open(fname,ios_base::in);
if (!file.is_open()){
cout<<"Невозможно открыть файл "<< fname <<"\n";
}
else{
while(!file.eof()){
T x;
file >> x;
lst.push_back(x);
}
}
file.close();
return;
}
template <typename T>
void OutputList(const List<T>& lst, char* fname){
fstream file;
file.open(fname,ios_base::out);
if (!file.is_open()){
cout<<"Невозможно открыть файл "<< fname <<"\n";
}
else{
for(int i = 0; i < lst.GetSize(); ++i){
file << lst[i] <<" ";
}
}
file<<"\n";
file.close();
return;
}
int main(int argc, char * argv[]) {
List< char > lst1;
List< int > lst2;
InputList(lst1,argv[1]);
InputList(lst2,argv[2]);
OutputList(lst1,argv[4]);
OutputList(lst2,argv[5]);
return 0;
}
Почему вы вдруг решили, что виноват "шаблонный класс"? Шаблонный класс тут совершенно ни при чем. Что вы сами в него положили, то там и лежит. Ошибок в вашем шаблоне хватает, но я думаю, что виноват в данном случае не он.
(И, кстати, как это вам удалось сделать определения методов шаблона в .cpp
файле?)
Последний элемент выводится дважды потому, что вы сами его занесли в список дважды. Вот он и выводится дважды.
Будете писать такие циклы
while(!file.eof()){
будете получать такие "ошибки". В вашей программе не должно быть циклов по eof()
. Это практически всегда ошибка.
См. Правильное использование проверки конца файла
Это тот случай, когда правильная запись компактнее и читабельней:
template <typename T>
void InputList(List<T>& lst, char* fname){
//...
else{
T x;
while(file >> x;)
lst.push_back(x);
}
//...
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Хотите улучшить этот вопрос? Добавьте больше подробностей и уточните проблему, отредактировав это сообщение
Дано натуральное число n (<= 100)Получить все простые числа, не превышающие это значение
Есть динамический массив объектов, как передать его в функцию и получить доступ к отдельному элементу?