Я пишу программу сопоставления файлов для проекта для школы. Идея в том, что одна программа позволяет вводить информацию следующим образом: 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;
}
c++
1
Chris 18 Мар 2011 в 03:54
Мне непонятно, в чем ваша проблема.
 – 
wilhelmtell
18 Мар 2011 в 03:59
Покажите нам код, который у вас уже есть.
 – 
Keith
18 Мар 2011 в 04:01
Можете ли вы показать нам версию с getline? Я думаю, что >> всегда будет прерываться на пробел: "Извлечение заканчивается, когда следующий символ является допустимым пробелом или нулевым символом, или если достигнут конец файла».
 – 
sarnold
18 Мар 2011 в 04:43
У меня никогда не было версии с работающим getline - было любопытно, правильно ли это дерево, чтобы лаять. Я не против потратить часы на изучение этого, но я не хочу часами лазить не по тому дереву больше, чем мне нужно.
 – 
Chris
18 Мар 2011 в 04:52

1 ответ

Лучше всего использовать как можно больше стандартной библиотеки C++. Держите под рукой справку, может быть, даже копию стандарта C++, если вы так склонны, и ищите ярлыки, которые сделают вашу работу проще, а код короче.

По возможности избегайте примитивных массивов и примитивных строк. Вместо примитивных массивов попробуйте использовать std::vector. Вместо примитивных строк попробуйте использовать std::string. Вместо C FILE* попробуйте использовать std::ofstream и std::ifstream. Если вам нужно запретить две учетные записи с одинаковым номером учетной записи, выберите контейнер C++, который гарантирует уникальные элементы. Если вам нужно найти элемент в контейнере, попробуйте использовать для поиска функцию-член контейнера, а если ее нет, то стандартную функцию поиска из стандартных алгоритмов C++.

Повторно используйте и безжалостно воруйте.

2
wilhelmtell 18 Мар 2011 в 04:01
1
Не возражаете, если я «повторно использую» последнюю строку? ;)
 – 
Maxpm
18 Мар 2011 в 04:28
Я люблю это. Между прочим, это путь, по которому я шел, но он не ведет меня туда, куда мне нужно идти. Я пытаюсь объединить, я думаю (все еще новый здесь) 2 строки в один .... массив? Думаю, я не знаю, куда идти, чтобы получить имя и фамилию в качестве одного из трех аргументов или блоков информации или чего-то еще, что здесь звучит умно.
 – 
Chris
18 Мар 2011 в 06:21
Несколько моментов о вашем коде. Вы очень хорошо начали. Сначала используйте конструктор ofstream для открытия файла: ofstream f("filename");. Тогда вам не нужно использовать f.open() и вам не нужно использовать f.close(), потому что конструктор и деструктор сделают это за вас. Кроме того, когда вы вызываете exit(1), ваши локальные объекты не очищаются. Вместо этого сообщите об ошибке для вызывающей стороны и, в конечном итоге, в main() верните код ошибки в операционную систему. По возможности избегайте exit().
 – 
wilhelmtell
18 Мар 2011 в 07:01
Затем, после вызова oldMaster.open(), вы проверяете поток с помощью operator!(), но сообщаете, что файл не открылся правильно. Это неправильно, это не то, что проверяет operator!(). Для этого у вас есть f.is_open(). Теперь внутри вашего цикла в createOldMaster() вы получаете ввод со стандартного ввода. Убедитесь, что вы проверяете успешность ввода: if( cin >> accountNum ) /*...*/ else /* failure */. Например, если пользователь вводит имя с буквами, когда он должен вводить номер счета, вы должны сообщить об ошибке.
 – 
wilhelmtell
18 Мар 2011 в 07:07
Теперь ваш вопрос. Проблема в том, что operator>>() для строк останавливается на пробеле. Итак, если ввод hello world, то когда вы извлекаете его в строку из std::cin, вы получаете только hello в строке. Опять же, это потому, что при форматированном чтении строк из std::cin (и именно это делает operator>>(); форматированный ввод) чтение останавливается на пробеле. Почему? Потому что в какой-то момент это должно остановиться. Это может быть новая строка, это может быть конец файла, это может быть первое число — библиотека не может сказать, что вам подходит. Таким образом, он останавливается на пробеле.
 – 
wilhelmtell
18 Мар 2011 в 07:11