корень вашей проблемы лежит в состоянии вашего Условный оператор в:
(myfile.peek() == std::ifstream::traits_type::eof())
Apperantly, файл открыт в режиме fstream в строке:
fstream myfile; myfile.open("CustomerFile.txt");
Теперь единственная причина, по которой я могу понять, почему условие вашего оператора if не выполняется, заключается в том, что режимы файлов различны. Я не уверен, прав я или нет (обратная связь приветствуется в окне комментариев), но это причина, по которой я могу придумать.
Я пробовал один из моих собственных методов, который всегда работает, и он также работал на ваш код. Я заменил следующие строки кода:
if (myfile.peek() == std::ifstream::traits_type::eof())
{
myfile << name + delimitor + password + delimitor + phonenbr << endl;
}
С этими линиями:
myfile.seekg (0, ios::end);
int length = myfile.tellg();
if (length == 0)
{
myfile << name + delimitor + password + delimitor + phonenbr << endl;
}
Первая линия myfile.seekg (0, ios::end);
Получает расстояние между 2 точками, указанными в скобках. 0 и ios :: end являются самоочевидными; 0 - это начало файла, а ios :: end - конец файла.
Вторая строка int length = myfile.tellg();
хранит значение, указанное в указанной строке в переменной int, называемой длиной. Длина - это количество символов, которые «курсор» должен был бы перемещать, чтобы получить от начала до конца этого файла (попробуйте представить курсор как мигающую вещь, подобную той, что находится в Microsoft Word, которая находится перед словом, которое вы ввод, кроме здесь, вы не можете видеть курсор в текстовом файле, перемещающемся от начала до конца).
Это, если условие довольно простое. Если длина равна нулю, это означает, что курсор должен переместить 0 пунктов, чтобы получить от начала файла до конца файла, а затем записать все, что вы хотите, в этот файл. Эта техника работала (по крайней мере, для меня).
На боковой ноте есть несколько других областей, где ваш код может улучшиться. Например, почему вы добавили, если-заявление:
if (!myfile.is_open())
{
myfile.open("CustomerFile.txt", ios::out);
}
Этот код представляет собой повторение этих строк кода:
fstream myfile; myfile.open("CustomerFile.txt");
.Open() команда уже выполняет Условный оператор Я указал. Если файл, указанный в open(), найден, тогда он откроет этот файл; иначе он будет продолжать создавать этот новый файл. Следовательно, этот if-statement является избыточным и должен быть удален, поскольку он потребляет ненужную мощность процессора и замедляет работу вашей программы (но не много, но вы скоро поймете, что каждая миллисекунда рассчитывает на запуск вашего кода, а эффективность - ключевой). Я бы рекомендовал вам удалить этот if-statement.
Другая проблема - ваши 3 переменные, которые вы принимаете для ввода. Учитывая, что это строки, почему вы используете метод cin >>? Использование cin будет принимать только первое слово в вашем предложении; в вашей следующей строке:
cout << "Name of the customer: "; cin >> name;
Если ввести John Doe, это будет только сохранить Джон имя переменного, и она будет двигаться «Doe» к следующему входным переменному, которая является паролем в вашем случае. Если нет другого cin, тогда он будет игнорировать слова после пробела. Поэтому используйте следующую строку для всех точек входа:
getline(cin, name);
Эта функция получит все слова и пространства как одного предложения до точки вы попали Enter, в отличие от КИН, что будет только первое слово и игнорировать остальная часть предложения.
И, наконец, ваш номер телефона должен иметь тип int. Я оставлю это для вас, чтобы исправить в соответствии с вашим требованием.
Надеюсь, я ответил на ваш вопрос и надеялся, что мои советы будут полезны. Удачи!
EDIT: Еще один момент, о котором я пропустил ваш код, заключался в том, что ваш цикл while работает для каждой строки. Это означает, что он будет проверять имя конкретного клиента в каждой отдельной строке файла. Это не то, что вы хотите. Вы хотите прочитать каждую строку в файле, НО, если вы найдете клиента, вы хотите завершить работу, не продолжая следующую строку. Кроме того, вы хотите распечатать только сообщение об ошибке ПОСЛЕ того, как вы прочитали весь файл, а не только одну строку.
else
{
int check = 0;
while (getline(myfile, buffer))
{
if (CheckIfCustomerExist(buffer, name, phonenbr) == true)
{
cout << "Customer already exist" << endl;
check = 1;
break;
}
}
if (check == 0)
{
myfile << name + delimitor + password + delimitor + phonenbr << endl;
cout << "Customer insert in the file " << endl;
}
}
Что делает этот фрагмент кода, так это то, что он проходит через каждую строку, проверяя клиента в этой строке. Если эта строка имеет запись клиента, то она устанавливает контрольное значение типа int в 1 из 0, и оператор break завершает цикл while. После прочтения всего файла он переходит к if-statement. В этом утверждении, если контрольная переменная все еще имеет 0, это означает, что у файла не было клиента, в котором новая запись будет добавлена в файл.
Кроме того, я сказал, что номер_телефона должен быть значением int. Я беру это как можно дальше и получаю от других пользователей StackOverflow, номер телефона лучше всего подходит как строковое значение, так как его формат может не храниться должным образом в качестве значения int (например, 0059875 будет сохранен как 59875).
Отключить тему: вам будет проще написать синтаксический анализатор, чтобы прочитать файл с помощью одного символьного разделителя. – user4581301