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

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

Но можно просто сортировать перед выводом и во 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 надо просто в массив добавлять, а файл не трогать.

Это просто дурдом какой-то. Ничего не работает. Вроде сделал как вы говорили, но все никак

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

using namespace std;

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

void Write(Phone *Myphone, int size)
{
	string name;
	string ini;
	string number;
	string email;
	for (int i = 0; i < size; i++)
	{
		cout << "Enter surname\n";
		getline(cin, name);
		cout << "Enter name or initials\n";
		getline(cin, ini);
		cout << "Enter phone number\n";
		getline(cin, number);
		cout << "Enter E-mail\n";
		getline(cin, email);
		Myphone[i].FIO = name[i] + " " + ini[i];
		Myphone[i].number = number[i];
		Myphone[i].email = email[i];
	}
}
void Rewrite(Phone* Myphone, int size)
{
	string res;
	ofstream fout("Phone_book.txt", ofstream::app);
	if (!fout)
	{
		cout << "Sorry i cant do it\n";
		return;
	}
	else
	{
		for (int i = 0; i < size; i++)
		{
			res = Myphone[i].FIO + " " + Myphone[i].number + " " + Myphone[i].email;
			fout << res << "\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(Phone* Myphone, int size, int index)
{
	string res;
	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;
	}
	cout << "Contact was succesfully deleted\n";
}
void Edit(Phone* Myphone, int size, int index)
{
	string res;
	string new_name;
	string new_number;
	string new_email;
	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;
	}
	cout << "Contact was succesfully edited\n";
}
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 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:
			Show(Myphone, count);
			break;
		case 3:
			Write(Myphone, count);
			count++;
			Sort("Phone_book.txt", Myphone, count);
			Rewrite(Myphone, count);
			break;
		case 4:
			index = Find(Myphone, count);
			Delete(Myphone, count, index);
			count--;
			Rewrite(Myphone, count);
			break;
		case 5:
			index = Find(Myphone, count);
			Edit(Myphone, count, index);
			Sort("Phone_book.txt", Myphone, count);
			Rewrite(Myphone, count);
			break;
		case 6:
			cout << "Good bye!\n";
			break;
		default:
			cout << "Wrong choice!\n";
			break;
		}
	} while (ans != 6);
	
}


Так тут наверно без цикла надо просто ввести один.

Ну и size до вызова увеличить, и писать в последний элемент.

Переделал, все равно не работает. Ввожу два элемента массива, если увеличиваю размер после вызова функции записи, то выводится первый элемент, а если после, то второй. Один элемент в любом случае продадает. То есть пропадает постоянно тот элемент, который после сортировки ниже. А оставшийся выводится в разных строках в зависимости от того где увеличил размер

Может как-то нужно поиграться с режимами открытия файлов? Я уже и не знаю что делать)

Как организовать этот отладочный вывод в моем коде. Я не могу понять. Завтра сдавать программу, ничего не понимаю уже

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

что-то странное тут :thinking:

Про ввод я так имел в виду:

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

using namespace std;

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

int Add(Phone* Myphone, int size)
{
    string name;
    string ini;
    string number;
    string email;
    cout << "Enter surname\n";
    getline(cin, name);
    cout << "Enter name or initials\n";
    getline(cin, ini);
    cout << "Enter phone number\n";
    getline(cin, number);
    cout << "Enter E-mail\n";
    getline(cin, email);

    Myphone[size].FIO = name + " " + ini;
    Myphone[size].number = number;
    Myphone[size].email = email;
    size++;

    return size;
}
void Rewrite(Phone* Myphone, int size)
{
    string res;
    ofstream fout("Phone_book.txt", ofstream::trunc);
    if (!fout)
    {
        cout << "Sorry i cant do it\n";
        return;
    }
    else
    {
        for (int i = 0; i < size; i++)
        {
            res = Myphone[i].FIO + " " + Myphone[i].number + " " + Myphone[i].email;
            fout << res << "\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(Phone* Myphone, int size, int index)
{
    string res;
    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;
    }
    cout << "Contact was succesfully deleted\n";
}
void Edit(Phone* Myphone, int size, int index)
{
    string res;
    string new_name;
    string new_number;
    string new_email;
    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;
    }
    cout << "Contact was succesfully edited\n";
}
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 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:
            Show(Myphone, count);
            break;
        case 3:
            count = Add(Myphone, count);
            Sort("Phone_book.txt", Myphone, count);
            Rewrite(Myphone, count);
            break;
        case 4:
            index = Find(Myphone, count);
            Delete(Myphone, count, index);
            count--;
            Rewrite(Myphone, count);
            break;
        case 5:
            index = Find(Myphone, count);
            Edit(Myphone, count, index);
            Sort("Phone_book.txt", Myphone, count);
            Rewrite(Myphone, count);
            break;
        case 6:
            cout << "Good bye!\n";
            break;
        default:
            cout << "Wrong choice!\n";
            break;
        }
    } while (ans != 6);
}

Добавил возврат size из Add на случай если захочется вводить больше 1 или проверять корректность ввода.

1 лайк

:arrow_down:

:arrow_down:
image

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);
            cout << "i: " << i << " ";
            cout << "buf: " << buff << "\n";
            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;
}
1 лайк

Ну все почти работает, но отладочный вывод не помог. Все равно с новым запуском программы появляется неполная строка с именем из последней строки. Но это уже не настолько страшно, в отличии от прошлых проблем. Хотя решить конечно хотелось бы и эту проблему. Вы очень помогли мне. Спасибо)

Но эта строка появляется только в консоли