Я пишу программу сопоставления файлов для проекта для школы. Идея в том, что одна программа позволяет вводить информацию следующим образом: 1000 (номер счета) Джейн Доу 54,50 (баланс). Затем позвольте вам ввести номер счета и сумму транзакции для второй программы, чтобы объединить и обновить новый мастер-файл.
Программы работают вместе просто отлично (вторая берет информацию из первой, включая любые транзакции и обновляет новый баланс - поиск по номеру счета), но проблема, с которой я сталкиваюсь, связана с именем.
--- Здесь не ясно. Когда я запрашиваю имя и ввожу одну строку символов, программа работает нормально, если я пытаюсь ввести полное имя, например Джейн Доу, я попадаю в цикл, упомянутый ниже.
Я попробовал char name[20], что помещает меня в бесконечный цикл, и мне нужно «x» выйти из программы, и я попытался присвоить first и lastName строке. Это сработало для записи, но программа, которая берет входной файл oldMaster и файл транзакции inTransaction, а затем выводит новый файл newMaster, не распознает имя.
Я также пробовал getline, который у меня не работает, возможно, ошибка программиста.
Должно ли это быть сделано как массив, если это возможно для этого? Кажется, я зацикливаюсь на том, что редактирую файлы. Ответы в порядке, но мне нравится разбираться в этом самостоятельно, просто ищу небольшое руководство о том, куда идти дальше.
Надеюсь, это было достаточно ясно - если нет, я буду рад снова объяснить по-другому. Просто расстроен, что я так близко и не могу решить.
Заранее спасибо!
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <iomanip>
using namespace std;
void createOldMaster()
{
ofstream oldMaster;
int accountNum;
double balance;
char name[15];
oldMaster.open("oldmast.dat", ios::out);
if(!oldMaster)
{
cout << "Unable to open the file." << endl;
exit(1);
} // end if
cout << "Enter the account number (0 to exit)." << endl;
while(true)
{
cout << "Account Number: ";
cin >> accountNum;
if(accountNum == 0)
break;
else
{
\\ This is where it hangs up if I use a first and last name
cout << "\nName: ";
cin >> name;
cout << "\nBalance : " << endl;
cin >> balance;
oldMaster << accountNum << " " << name << " " << balance << endl;
}
}
} //end createOldMaster
void createTransaction()
{
ofstream inTransaction;
int accountNum;
double balance;
inTransaction.open("trans.dat");
if(!inTransaction)
{
cout << "Unable to open the transaction file." << endl;
exit(1);
}
cout << "Enter the account number and balance (0 to exit): " << endl;
while(true)
{
cout << "Account Number: " << endl;
cin >> accountNum;
if(accountNum == 0)
break;
else
{
cout << "Balance: " << endl;
cin >> balance;
inTransaction << accountNum << " " << balance << endl;
}
}
} //end createTransaction
int main()
{
createOldMaster();
createTransaction();
return 0;
}
1 ответ
Лучше всего использовать как можно больше стандартной библиотеки C++. Держите под рукой справку, может быть, даже копию стандарта C++, если вы так склонны, и ищите ярлыки, которые сделают вашу работу проще, а код короче.
По возможности избегайте примитивных массивов и примитивных строк. Вместо примитивных массивов попробуйте использовать std::vector
. Вместо примитивных строк попробуйте использовать std::string
. Вместо C FILE*
попробуйте использовать std::ofstream
и std::ifstream
. Если вам нужно запретить две учетные записи с одинаковым номером учетной записи, выберите контейнер C++, который гарантирует уникальные элементы. Если вам нужно найти элемент в контейнере, попробуйте использовать для поиска функцию-член контейнера, а если ее нет, то стандартную функцию поиска из стандартных алгоритмов C++.
Повторно используйте и безжалостно воруйте.
ofstream
для открытия файла: ofstream f("filename");
. Тогда вам не нужно использовать f.open()
и вам не нужно использовать f.close()
, потому что конструктор и деструктор сделают это за вас. Кроме того, когда вы вызываете exit(1)
, ваши локальные объекты не очищаются. Вместо этого сообщите об ошибке для вызывающей стороны и, в конечном итоге, в main()
верните код ошибки в операционную систему. По возможности избегайте exit()
.
oldMaster.open()
, вы проверяете поток с помощью operator!()
, но сообщаете, что файл не открылся правильно. Это неправильно, это не то, что проверяет operator!()
. Для этого у вас есть f.is_open()
. Теперь внутри вашего цикла в createOldMaster()
вы получаете ввод со стандартного ввода. Убедитесь, что вы проверяете успешность ввода: if( cin >> accountNum ) /*...*/ else /* failure */
. Например, если пользователь вводит имя с буквами, когда он должен вводить номер счета, вы должны сообщить об ошибке.
operator>>()
для строк останавливается на пробеле. Итак, если ввод hello world
, то когда вы извлекаете его в строку из std::cin
, вы получаете только hello
в строке. Опять же, это потому, что при форматированном чтении строк из std::cin
(и именно это делает operator>>()
; форматированный ввод) чтение останавливается на пробеле. Почему? Потому что в какой-то момент это должно остановиться. Это может быть новая строка, это может быть конец файла, это может быть первое число — библиотека не может сказать, что вам подходит. Таким образом, он останавливается на пробеле.
Похожие вопросы
Новые вопросы
c++
C ++ - это язык программирования общего назначения. Первоначально он был разработан как расширение C и имеет аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде (который должен быть) скомпилирован с помощью компилятора C ++. Используйте тег для конкретной версии для вопросов, связанных с конкретной версией стандарта [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] или [C ++ 23] и т. Д. .
getline
? Я думаю, что>>
всегда будет прерываться на пробел: "Извлечение заканчивается, когда следующий символ является допустимым пробелом или нулевым символом, или если достигнут конец файла».