2010-11-05 2 views
1

Хорошо, будьте осторожны, так как я начинаю программировать. До сих пор я изучал только C++, и я запускаю Visual Studio 2010 в качестве моего компилятора. Для этой программы я пытаюсь читать из текстового входного файла и записывать информацию в набор из трех массивов. Один массив будет обрабатывать список имен, а два других - отработанных часов и часовой оплаты, соответственно. Я буду использовать последние два для вычисления набора доходов и вывода этих вычислений в другой текстовый файл. Моя проблема, однако, заключается в получении ввода для первого массива. Входной файл, я использую имеет текст, расположенный так:Чтение ввода из текстового файла в массив в C++

J. Doe * 35 12,50

J. Рассвет * 20 10,00 .........

Имена когда я пытаюсь использовать getstream getline для получения имен со звездочками, действующих как разделители, и записывая следующие два числа в два других массива. Последние два значения разделены пробелами, поэтому я не думаю, что они вызовут какие-либо проблемы. Я уверен, что есть и другие ошибки, которые требуют обработки, но мне нужно проработать первую ошибку, прежде чем я смогу начать отладку остальных. Возникает ошибку с линией, где я называю inFile.getline, который гласит:

ошибка C2664: «зОго :: basic_istream < _Elem, _Traits> & зОго :: basic_istream < _Elem, _Traits> :: getline (_Elem *, std :: streamsize, _Elem) ': не может преобразовать параметр 1 из' std :: string 'в' char * '.

Из того, что я читал в другом месте, я думаю, проблема связана с попыткой написать строку в массив символов, который не будет работать, поскольку они имеют разные типы данных. Я не уверен, существуют ли другие возможные методы для получения имен, поскольку мне нужен разделитель, чтобы отделить имена от числовых значений. Любые рекомендации о том, как решить эту проблему, будут высоко оценены.

Вот источник я написал:

#include <iostream> 
#include <fstream> 
#include <iomanip> 
#include <string> 
using namespace std; 

const int EMP_NUM = 5; 
const int BASE_HOURS = 40; 
const char N_SIZE = 8; 

int main() 
{ 
int i; 
double rEarnings, oEarnings, tEarnings, 
trEarnings, toEarnings, ttEarnings; 
ifstream inFile; 
ofstream outFile; 
inFile.open("records.txt"); 
outFile.open("report.txt"); 

outFile << setprecision(2) << showpoint << fixed; 

outFile << setw(50) << "Payroll Report" << "\n\n"; 
outFile << "EMPLOYEE NAME" << setw(25) << "REGULAR EARNINGS" << setw(25) << "OVERTIME EARNINGS" << setw(25) << "TOTAL EARNINGS" << endl; 

string nameAr[EMP_NUM]; 
int hoursAr[EMP_NUM]; 
double hrateAr[EMP_NUM]; 

for (int i = 0; i < EMP_NUM; i++) // Get input from our input file. 
{ 
    inFile.getline(nameAr[i], EMP_NUM, "*"); 
    inFile >> hoursAr[i] >> hrateAr[i]; 
} 

for (int i = 0; i < EMP_NUM; i++) // Make the calculations to be sent to our report. 
{ 
    char nameAr[N_SIZE]; 
    int hoursAr[N_SIZE]; 
    double hrateAr[N_SIZE]; 

    if (hoursAr[i] > 40) // For employees with overtime hours. 
    { 
    // double rEarnings, double oEarnings, double tEarnings, 
    // double trEarnings, double toEarnings, double ttEarnings; 
    // rEarnings = 0, oEarnings = 0, tEarnings = 0, 
    // trEarnings = 0, toEarnings = 0, ttEarnings = 0; 

    rEarnings = BASE_HOURS * hrateAr[i]; 
    oEarnings = (hoursAr[i] - BASE_HOURS) * hrateAr[i] * 1.5; 
    tEarnings = rEarnings + oEarnings; 
    trEarnings += rEarnings; 
    toEarnings += oEarnings; 
    ttEarnings += tEarnings; 
    outFile << left << nameAr[i]; 
    // << setw(25) << right << rEarnings << setw(25) << right << oEarnings << setw(25) << right << tEarnings << endl; 

    } 
    else // For employees without overtime hours. 
    { 
    double rEarnings, double oEarnings, double tEarnings, 
    double trEarnings, double toEarnings, double ttEarnings; 
    rEarnings = 0, oEarnings = 0, tEarnings = 0, 
    trEarnings = 0, toEarnings = 0, ttEarnings = 0; 

    rEarnings = hoursAr[i] * hrateAr[i]; 
    oEarnings = 0; 
    tEarnings = rEarnings + oEarnings; 
    trEarnings += rEarnings; 
    toEarnings += oEarnings; 
    ttEarnings += tEarnings; 
    outFile << left << nameAr[i] << setw(25) << right << rEarnings << setw(25) << right << oEarnings << setw(25) << right << tEarnings << endl; 
    } 
} 

outFile << endl << endl; 

outFile << setw(33) << trEarnings << " *" << setw(23) << toEarnings << " *" << setw(23) << ttEarnings << " *\n\n"; 

outFile << left << "TOTAL EMPLOYEES" << " " << (i - 1); 

inFile.close(); outFile.close(); 

return 0; 
} 

Я включил всю программу, чтобы дать вам представление о том, где я планирую поехать с кодировкой. Заранее спасибо за помощь!

+0

Чувства, подобные дежавю: http://stackoverflow.com/questions/4108811/reading-input-from-text-file-to-array-in-c – birryree

+0

Они оба выполняют одно и то же домашнее задание? – hyprsleepy

+0

Я думаю, что они одни и те же люди, поскольку оба они имеют одинаковый точный код. – birryree

ответ

1

Здравствуйте C++ новый программист! Добро пожаловать в удивительность кодирования в C/C++.

Я знаю, что вы только что начали C++. Но чтобы исправить вашу проблему, нам нужно коснуться немного C. C++, так что это супермножество C. Значение всего, что можно сделать в C, будет работать в C++-программе.

Достаточно слов, кодовое время. Замените код, который вы используете для ввода ввода из вашего входного файла, следующим образом:

char tmp[256]; 
memset(tmp, '\0', sizeof tmp); 
inFile.getline(tmp, EMP_NUM, '*'); 
nameAr[i] = tmp; 
inFile >> hoursAr[i] >> hrateAr[i]; 

Давайте пройдем через него.

char tmp[256]; Создает временный массив для чтения значений. Размер этого массива может варьироваться в зависимости от средней длины имен, которые вы получаете.

Струны в C - это как чистые чипы для обслуживания. Вы должны указать NULL-символ '\0' в конце, или они могут привести к сбою вашей программы с не столь очевидными ошибками сегментации. Тем не менее, Memset - это маленький человек, который работает в шахтах компьютера; он поможет нам исправить это. Когда вызывается в этой форме memset(tmp, '\0', sizeof tmp), memset начинается с адреса tmp, просматривает все биты массива - идентификатор размера, указанный как sizeof tmp, - и устанавливает эти биты в указанный символ - в этом случае NULL. Таким образом, нам не нужно было бы помнить о добавлении символа NULL каждый раз, когда мы читаем строку C; при условии, что размер tmp достаточно велик. Удобный!

inFile.getline(tmp, EMP_NUM, '*'); считывает вход [string] из вашего файла, как ожидалось, и сохраняет его в tmp.

nameAr[i] = tmp; помещает ввод в массив имен.

и, наконец, inFile >> hoursAr[i] >> hrateAr[i]; читает часы и почасовые ставки, как раньше.

Надеюсь, что это поможет.

Приветствия! Счастливое обучение.

1

Таким образом, я бы не использовал getline, потому что у вас есть два отдельных символа разделителя, которые имеют дело с пространством и звездочкой. Вот что я бы сделал вместо этого:

Используйте getline, чтобы получить ПОЛНУЮ строку в string по номеру line.

Найти звездочку с помощью line.find('*');

Extract имени в качестве нового string, используя line.substr до позиции только что

substr Возьми другой за пределами звездочки в stringstream называется remainder.

Читать int и double непосредственно из него с помощью operator>>: remainder >> hours >> rate;