程序不计算记录数

时间:2012-11-25 06:41:28

标签: c++ ifstream

我写了一个程序,它读取到一个文件,写入另一个文件并打印到屏幕上。换句话说,它应该做三件事(即读,写和打印)。

该程序还应该计算名为“Chap_11_employee_data.txt”的文件中的记录数。然而,它只是显示以下内容。

**Total Records 0** 
    The End

当它写入文件时,它还会显示奇怪的数字,例如-858993460。我几乎尝试了一切,这使我在这里注册了一个帐户。下面列出了我的代码以及我尝试读取的文件和我尝试写入的文件。

非常感谢你的家伙。

代码:

#include <iostream>
#include <fstream>  
#include <iomanip>  
using std::cin;
using std::cout;
using std::endl;
using std::setw;
using std::ios;

using std::ifstream;
using std::ofstream;

const int EMPLOYEES = 20; 
const int MAX = 21;  

int ReadData( ifstream &inFile, ofstream &outFile, char name[][MAX], int age[] );
void WriteOutputFile( ofstream &outFile, char name[ ][MAX], int age[ ], int counter );
void PrintTotalsAndSummary( ofstream &out, int totalRecords );

int main()
{   
    char name[EMPLOYEES][MAX]; 
    int age[EMPLOYEES];
    int record_counter(0);

    ifstream inFile;    

    ofstream outFile( "Chap_11_Report.txt" );  

    inFile.open( "Chap_11_employee_data.txt" );  

    if ( inFile.is_open() )   
    {   
        record_counter = ReadData( inFile, outFile, name, age );
        inFile.close();

        if( outFile.is_open() )
        {   
            WriteOutputFile( outFile, name, age, record_counter );
            PrintTotalsAndSummary( outFile, record_counter );
            outFile.close();            
        }   
        else
        {   
            cout << "Trouble Opening File";  
            cout << "\n\n\t\t ** About to EXIT NOW! ** ";
        }   
    }   
    else
    {   
        cout << "Trouble Opening File";
        cout << "\n\n\t\t ** About to EXIT NOW! ** ";
    }   
    return 0;
}
int ReadData( ifstream & inFile, ofstream & outFile, char name[][MAX], int age[] )
{   
    int counter = 0;
    inFile >> name[counter] >> age[counter]; // Priming Read

    while ( !inFile.eof() )
    {
        cout << setiosflags( ios::left ) << setw( 25 )
            <<  name[counter] << resetiosflags( ios::left )
            << setw( 4 ) << age [counter] << endl;
        counter++;
        inFile >> name[counter] >> age[counter];
    }

    return counter;
}


void WriteOutputFile( ofstream &outFile, char name[][MAX], int age[], int counter)
{
    outFile << "   Here is the Output File" << endl;
    for ( int r = 0; r <= counter; r++ )
    {
        outFile << setiosflags( ios::left ) << setw( 25 )
            << name[r] << setw( 4 )
            << resetiosflags( ios::left ) << age[r]
            << endl;
    }
}

void PrintTotalsAndSummary( ofstream &outFile, int totalRecords )
{
    // To screen
    cout  << "\n\n\t** Total Records: " << totalRecords << " **\n"
        << "\t\t The End \n";

    // To file
    outFile << "\n\n\t** Total Records: " << totalRecords << " **\n"
        << "\t\t The End \n";
}

我正在阅读的文件(Chap_11_employee_data.txt):

"Alexis","Blough",1-1921,"CEO"
"Bill","Pay",1-7711,"Accounting"
"Willy","Makit",4-1595,"Sales"
"Marie","Murray",1-4986,"MIS"
"Cal","Caldwellowinski",5-0911,"MIS"
"Jamie","Johanasola",5-9999,"Marketing"

我写的文件(Chap_11_Report.txt):

Here is the Output File
                     -858993460


    ** Total Records: 0 **
         The End 

2 个答案:

答案 0 :(得分:2)

这是您的输入声明......

inFile >> name[counter] >> age[counter]; 

输出文件格式是这个......

"Alexis","Blough",1-1921,"CEO"
"Bill","Pay",1-7711,"Accounting"

输入语句读取名称,直到遇到空格或结束字符。所以在第一种情况下,它会读取整行,因为单词之间没有空格。接下来,它将输入年龄,这是一个int。它将从第二行开始接受年龄输入,第二行从一开始就充满了字符。整数流中的字符是未定义的行为。这就是你得到错误结果的原因。

问题是文件格式与输入格式不匹配。尝试同步它们。

要阅读空格,请使用inFile.get()inFile.getline()

答案 1 :(得分:1)

您的阅读有一个问题:

while ( !inFile.eof() )

问题是流可能以不是eof()的方式变坏。如果发生这种情况,您将进入无限循环。所以你应该检查一下bad()。

while ( !inFile.bad() ) // check for eof and other error cases.

通常这个测试是完全错误的。但是你已经设法通过以下方式来解决这个问题:

<Get Input>

while ( !inFile.bad() )
{
    < DO WORK>
    <Get Input>
}

可以通过以下方式实现相同的效果(以更惯用的方式):

while ( <Get Input> )
{
    < DO WORK>
}

read(使用&gt;&gt;或std :: getline())返回对流的引用。当它在布尔上下文中使用时(如while循环测试),它将转换为bool(实际上是语言律师的bool),它表示使用bad获得的流的状态。因此,仅当读取实际有效时才输入循环体。

输入流操作符非常简单,输入上的任何失败都会在流内部设置一个内部故障位,导致它们在重置故障位之前不会提供进一步的输入。

根据您提供的输入,这将失败:

inFile >> name[counter] >> age[counter];

变量name[counter]表示C-String,输入运算符&gt;&gt;当应用于C-String时,将读取直到第一个空格字符(在本例中为换行符)。所以我们在这里指定:

"Alexis","Blough",1-1921,"CEO"

到这个值。

然后我们尝试使用age[counter]整数值继续阅读。这会尝试从以下位置读取整数:

"Bill","Pay",1-7711,"Accounting"

这将失败,因为字符'"'不是数字。

你应该做的是:

std::string  name;
std::getline(inFile, name, ','); // Read upto the ',' character (and discard it)
// You may want to remove the quotes here.

int age = 0;
// Age is not defined in the input so set it manually.

std::string  line;
std::getline(inFile, line);      // Read and ignore the rest of the line.