Телефонная книга, появляется лишний элемент при каждом запуске

void main()
{
    int const size = 100;
	Phone Myphone[size];
	int index = 0;
	int count = Read("Phone_book.txt", Myphone);
	int ans;
	do
	{
		cout << "Enter what you want to do\n";
		cout << "1 - Find number\n";
		cout << "2 - Show all numbers\n";
		cout << "3 - Add number\n";
		cout << "4 - Delete number\n";
		cout << "5 - Edit number\n";
		cout << "6 - Exit\n";
		cin >> ans;
		cin.get();
		switch (ans)
		{
		case 1:
			Find(Myphone, count);
			break;
		case 2:
			Sort("Phone_book.txt", Myphone, count);
			Show(Myphone, count);
			break;
		case 3:
			Write("Phone_book.txt", Myphone);
			Read("Phone_book.txt", Myphone);
			count++;
			break;
		case 4:
			index = Find(Myphone, count);
			Delete("Phone_book.txt", Myphone, count, index);
			Read("Phone_book.txt", Myphone);
			count--;
			break;
		case 5:
			index = Find(Myphone, count);
			Edit("Phone_book.txt", Myphone, count, index);
			break;
		case 6:
			cout << "Good bye!\n";
			break;
		default:
			cout << "Wrong choice!\n";
			break;
		}
	} while (ans != 6);
	
}

Ну вот мэйн. Вы тут смеетесь надо мной, а я и сон потерял и покой))))

Так а что в Show и Sort?

Проще и надежнее так:

count = Read("Phone_book.txt", Myphone);

Или убрать Read, он же тут не нужен.

void Sort(const char* filename, Phone*Myphone , int size)
{
	string res;
	ofstream fout(filename, ofstream::out);
	for (int i = 0; i < size; i++)
	{
		for (int j = 0; j < size - 1; j++)
		{
			if (Myphone[j].FIO > Myphone[j + 1].FIO)
			{
				swap(Myphone[j], Myphone[j + 1]);
			}
		}
	}
	for (int i = 0; i < size; i++)
	{
		res = Myphone[i].FIO + " " + Myphone[i].number + " " + Myphone[i].email;
		fout << res << "\n";
	}
	fout.close();
}
void Show(Phone* Myphone, int size)
{
	cout << "#\tFIO\t\tPhone Number\t\tE-mail\n";
	for (int i = 0; i < size; i++)
	{
		cout << i + 1 << "\t" << Myphone[i].FIO << "\t" << Myphone[i].number << "\t" << Myphone[i].email << "\n";
	}
}

ну вот

#include<sstream>
#include<iostream>
#include<fstream>
#include<string>

using namespace std;

struct Phone
{
	string number;
	string FIO;
	string email;
	
};

void Write(const char* filename, Phone *Myphone)
{
	string name;
	string ini;
	string phone_number;
	string email;
	string rez;
	ofstream fout(filename, ofstream::app);
	if (!fout)
	{
		cout << "Sorry i cant do it\n";
		return;
	}
	else
	{
		cout << "Enter surname\n";
		getline(cin, name);
		cout << "Enter name or initials\n";
		getline(cin, ini);
		cout << "Enter phone number\n";
		getline(cin, phone_number);
		cout << "Enter E-mail\n";
		getline(cin, email);
		rez = name + " " + ini + " " + phone_number + " " + email;
		fout << rez << "\n";		
	}
	fout.close();
}
int Read(const char* filename, Phone* Myphone)
{
	int size = 0;
	ifstream fin(filename);
	if (!fin)
	{
		cout << "Your Phone book is empty\n";
	}
	else
	{
		string buff;
		string name;
		string ini;
		int i = 0;
		while (!fin.eof())
		{
			getline(fin, buff);
			stringstream ss(buff);
			ss >> name;
			ss >> ini;
			Myphone[i].FIO = name + " " + ini;
			ss >> Myphone[i].number;
			ss >> Myphone[i].email;
			i++;
			size++;
		}
	}
	fin.close();
	return size;
}
void Delete(const char* filename, Phone* Myphone, int size, int index)
{
	string res;
	ofstream fout(filename, ofstream::trunc);
	
	for (int i = index; i < size - 1; i++)
	{

		Myphone[i].FIO = Myphone[i+1].FIO;
		Myphone[i].number = Myphone[i+1].number;
		Myphone[i].email = Myphone[i+1].email;
	}
	for (int i = 0; i < size - 1; i++)
	{
		res = Myphone[i].FIO + " " + Myphone[i].number + " " + Myphone[i].email;
		fout << res << "\n";
	}
	cout << "Contact was succesfully deleted\n";
	fout.close();
}
void Edit(const char* filename, Phone* Myphone, int size, int index)
{
	string res;
	string new_name;
	string new_number;
	string new_email;
	ofstream fout(filename, ofstream::out);
	for (int i = index; i < index + 1; i++)
	{
		Myphone[i].FIO = "";
		Myphone[i].number = "";
		Myphone[i].email = "";
		cout << "Enter new name\n";
		getline(cin, new_name);
		cout << "Enter new number\n";
		cin >> new_number;
		cout << "Enter new E-mail\n";
		cin >> new_email;
		Myphone[i].FIO = new_name;
		Myphone[i].number = new_number;
		Myphone[i].email = new_email;
	}
	for (int i = 0; i < size; i++)
	{
		res = Myphone[i].FIO + " " + Myphone[i].number + " " + Myphone[i].email;
		fout << res << "\n";
	}
	cout << "Contact was succesfully edited\n";
	fout.close();
}
void Sort(const char* filename, Phone*Myphone , int size)
{
	string res;
	ofstream fout(filename, ofstream::out);
	for (int i = 0; i < size; i++)
	{
		for (int j = 0; j < size - 1; j++)
		{
			if (Myphone[j].FIO > Myphone[j + 1].FIO)
			{
				swap(Myphone[j], Myphone[j + 1]);
			}
		}
	}
	for (int i = 0; i < size; i++)
	{
		res = Myphone[i].FIO + " " + Myphone[i].number + " " + Myphone[i].email;
		fout << res << "\n";
	}
	fout.close();
}
void Show(Phone* Myphone, int size)
{
	cout << "#\tFIO\t\tPhone Number\t\tE-mail\n";
	for (int i = 0; i < size; i++)
	{
		cout << i + 1 << "\t" << Myphone[i].FIO << "\t" << Myphone[i].number << "\t" << Myphone[i].email << "\n";
	}
}
int Find(Phone* Myphone,int size)
{
	bool found = false;
	int ans;
	int index = 0;
	string f_name, f_mail, f_number;
	cout << "Find by: \n";
	cout << "1 - Name\n";
	cout << "2 - Number\n";
	cout << "3 - E-mail\n";
	cin >> ans;
	cin.get();
	switch (ans)
	{
	case 1:
		cout << "Please enter Name: ";
		getline (cin,f_name);
		for (int i = 0; i < size; i++)
		{
			if (f_name == Myphone[i].FIO)
			{
				cout << "Found!\n";
				cout << Myphone[i].FIO << ' ' << Myphone[i].number << ' ' << Myphone[i].email << "\n";
				found = true;
				index = i;
			}
		}
		break;
	case 2:
		cout << "Please enter Number: ";
		cin >> f_number;
		for (int i = 0; i < size; i++)
		{
			if (f_number == Myphone[i].number)
			{
				cout << "Found!\n";
				cout << Myphone[i].FIO << ' ' << Myphone[i].number << ' ' << Myphone[i].email << "\n";
				found = true;
				index = i;
			}
		}
		break;
	case 3:
		cout << "Please enter E-mail: ";
		cin >> f_mail;
		for (int i = 0; i < size; i++)
		{
			if (f_mail == Myphone[i].email)
			{
				cout << "Found!\n";
				cout << Myphone[i].FIO << ' ' << Myphone[i].number << ' ' << Myphone[i].email << "\n";
				found = true;
				index = i;
			}
		}
		break;
	default:
		cout << "Wrong command\n";
		break;
	}

	if (!found)
		cout << "Sorry, there are no any data\n";

	cout << "\n";
	cin.clear();
	return index;
}

void main()
{
    int const size = 100;
	Phone Myphone[size];
	int index = 0;
	int count = Read("Phone_book.txt", Myphone);
	int ans;
	do
	{
		cout << "Enter what you want to do\n";
		cout << "1 - Find number\n";
		cout << "2 - Show all numbers\n";
		cout << "3 - Add number\n";
		cout << "4 - Delete number\n";
		cout << "5 - Edit number\n";
		cout << "6 - Exit\n";
		cin >> ans;
		cin.get();
		switch (ans)
		{
		case 1:
			Find(Myphone, count);
			break;
		case 2:
			Sort("Phone_book.txt", Myphone, count);
			Show(Myphone, count);
			break;
		case 3:
			Write("Phone_book.txt", Myphone);
			Read("Phone_book.txt", Myphone);
			count++;
			break;
		case 4:
			index = Find(Myphone, count);
			Delete("Phone_book.txt", Myphone, count, index);
			count--;
			break;
		case 5:
			index = Find(Myphone, count);
			Edit("Phone_book.txt", Myphone, count, index);
			break;
		case 6:
			cout << "Good bye!\n";
			break;
		default:
			cout << "Wrong choice!\n";
			break;
		}
	} while (ans != 6);
	
}


Вот весь код, одна надежда осталась на вас)

Зачем файл перезаписывать при выводе/сортировке?

Если он должен храниться отсортированным, то тогда и при добавлении элемента (3 пункт) нельзя в конец добавлять, надо тоже сортировать и перезаписывать всё.

Или хранить как попало и сортировать перед выводом.

Но при выводе (2 пункт) перезаписывать файл в любом случае не надо, только при добавлении/удалении.


А про текущую проблему с появлением лишнего элемента — может быть при чтении

работает не так, как задумывалось, и останавливается позже.

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

То есть и тут нужна функция Read?

index = Find(Myphone, count);
			Delete("Phone_book.txt", Myphone, count, index);
			count--;
string res;
	ofstream fout(filename, ofstream::out);
	for (int i = 0; i < size; i++)
	{
		for (int j = 0; j < size - 1; j++)
		{
			if (Myphone[j].FIO > Myphone[j + 1].FIO)
			{
				swap(Myphone[j], Myphone[j + 1]);
			}
		}
	}
	for (int i = 0; i < size; i++)
	{
		res = Myphone[i].FIO + " " + Myphone[i].number + " " + Myphone[i].email;
		fout << res << "\n";
	}
	fout.close();

А тут вместо ofstream fout(filename, ofstream::out), ofstream fout(filename, ofstream::trunc)? Верно?

А зачем читать файл когда-либо после чтения при запуске программы?
В массиве же и так текущая версия.

Я же говорю

Sort нужно выполнять внутри Write что ли?

Сделал вот это, но все равно не работает

void Write(const char* filename, Phone *Myphone, int size)
{
	string name;
	string ini;
	string phone_number;
	string email;
	string res;
	ofstream fout(filename, ofstream::trunc);
	if (!fout)
	{
		cout << "Sorry i cant do it\n";
		return;
	}
	else
	{
		cout << "Enter surname\n";
		getline(cin, name);
		cout << "Enter name or initials\n";
		getline(cin, ini);
		cout << "Enter phone number\n";
		getline(cin, phone_number);
		cout << "Enter E-mail\n";
		getline(cin, email);

		for (int i = 0; i < size; i++)
		{
			for (int j = 0; j < size - 1; j++)
			{
				if (Myphone[j].FIO > Myphone[j + 1].FIO)
				{
					swap(Myphone[j], Myphone[j + 1]);
				}
			}
		}
		for (int i = 0; i < size; i++)
		{
			res = name + " " + ini + " " + phone_number + " " + email;
			fout << res << "\n";
		}
	}
	fout.close();
}

Если зачем-то нужно хранить отсортированный файл, то да.

Но можно просто сортировать перед выводом и во 2 пункте вообще не трогать файл.

Ну как же? Я уже и внутри Write пытался сделать сортировку и в мэйн ставил в начале Сорт. Ну тупик какой-то)))

Так а проблема-то в чем именно?
Надо определиться что нужно достичь:

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

Но это отдельная проблема не связанная с лишним элементом, про него было тут:

Преподаватель говорит, что нужно хранить отсортированный список файле

Тогда нужно

  1. Сделать
  2. Вызывать Rewrite в 3, 4, 5 пунктах после изменения массива. И либо внутри Rewrite, либо до её вызова в 3 и 5 пунктах вызывать Sort (которая должна просто сортировать массив).
    2.1. Write лучше переименовать в Add и в ней добавлять элемент в массив (size++ и записывать данные в последний элемент), вызывать Rewrite.
void Rewrite(Phone* Myphone, int size)
{
	string res;
	ofstream fout("Phone_book.txt");
	for (int i = 0; i < size; i++)
	{
		res = Myphone[i].FIO + " " + Myphone[i].number + " " + Myphone[i].email;
		fout << res << "\n";
	}
	fout.close();
}

не работает все равно

Что именно?

Делаю заполнение, а когда вывожу в консоль, выводятся просто строки пустые

Write("Phone_book.txt", Myphone);
			count++;
			Sort("Phone_book.txt", Myphone, count);
			Rewrite(Myphone, count);

Так я ж только что писал, что это другая отдельная проблема, не связанная с Rewrite и сортировкой:


Или если все пустые после добавления, то видимо сейчас что-то не так в Write или Sort.

void Sort(const char* filename, Phone*Myphone , int size)
{
	for (int i = 0; i < size; i++)
	{
		for (int j = 0; j < size - 1; j++)
		{
			if (Myphone[j].FIO > Myphone[j + 1].FIO)
			{
				swap(Myphone[j], Myphone[j + 1]);
			}
		}
	}
}

void Write(const char* filename, Phone *Myphone)
{
	string name;
	string ini;
	string phone_number;
	string email;
	string res;
	ofstream fout(filename, ofstream::app);
	if (!fout)
	{
		cout << "Sorry i cant do it\n";
		return;
	}
	else
	{
		cout << "Enter surname\n";
		getline(cin, name);
		cout << "Enter name or initials\n";
		getline(cin, ini);
		cout << "Enter phone number\n";
		getline(cin, phone_number);
		cout << "Enter E-mail\n";
		getline(cin, email);			
		res = name + " " + ini + " " + phone_number + " " + email;
		fout << res << "\n";
		
	}
	fout.close();
}

Ну они вроде не изменились

Так во Write надо просто в массив добавлять, а файл не трогать.