strcmp()函数无法与用户输入和结构文件数据进行正确比较

时间:2014-10-25 11:50:18

标签: c++ file struct fstream strcmp

我正在尝试解决这个问题,当我尝试在我的.dat文件中搜索某个模块名称时,它不会显示模块名称,模块代码等模块的信息。

示例:如果我搜索CSCI124,它会显示我在输出中需要的所有信息。 但是,如果我尝试搜索CSCI114或MATH121,除了“找不到主题代码”外,它不会显示任何信息。

我尝试过不使用while循环,但是它不能正常工作。

如果你们可以帮助我,开始学习c ++

,那将是非常棒的
Subject subjectDB;
char subCode[MAX];
int printOnce = 0;
int position = 0;

cout << "Enter Subject Code: ";
cin >> subCode;

// Open binary file
ifstream fin("Subject.dat", ios::out | ios::binary);

if (!fin)
{
    cout << "\nError opening database..\n"
         << "\tQuitting System..";
    exit(-1);
}

cin.clear();
cin.ignore(100, '\n');

while(fin.read(reinterpret_cast<char*>(&subjectDB), sizeof(Subject)))
{
    if (!(strcmp(subCode, subjectDB.subjectCode) == 0))
    {
        // Print this section once
        if (printOnce == 0)
        {
            cout << "Subject Code not found..\n";
            printOnce++;
        }
    }

    else
    {
        // Print this section once
        if (printOnce == 0)
        {
            cout << "\nSubject Code: "
                 << subjectDB.subjectCode
                 << "\nSubject Name: "
                 << subjectDB.subjectName
                 << "\n"
                 << endl;

            cout << "Task\t"
                 << "Title\t\t"
                 << "Weight\t"
                 << "Upon\t"
                 << "Mark\t"
                 << "Obtained\n";

            // PrintOnce++ : 1 != 0
            // So it only prints once
            printOnce++;
        }


        cout << position + 1
             << "\t"
             << subjectDB.assessment[position].title
             << "\t"
             << subjectDB.assessment[position].weight
             << "\t"
             << subjectDB.assessment[position].upon
             << "\t"
             << subjectDB.assessment[position].taskMark
             << "\t"
             << "testing\n";

             position++;
    }   
}

3 个答案:

答案 0 :(得分:0)

将结构写入文件或从文件中读取结构是完全不可移植的。在两个不同的编译器上编译相同的代码,或者在具有不同设置的相同编译器上编译相同的代码,并且您编写的内容和您阅读的内容可能会有很大不同。这不一定是你的问题,但有一天它会是你的问题。

答案 1 :(得分:0)

您的显示代码逻辑存在缺陷。

<强>解释

如果主题代码在您阅读的第一条记录中,您将得到正确的答案。但是,只要您的第一个记录不匹配,就会发现&#34;未找到&#34;显示消息,printOnce递增。如果稍后在文件中找到匹配的主题coe,则printOnce不再为0并且它是&#39;将不会显示。

<强>解决方案:

以相反的方式组织你的循环:

while (...)  {
    if (strcmp(..)==0) {
         // your code to display the found item here
         printOnce++;
         break; // ?? optional: you could stop the loop at first found occurence unless you suppose there could be duplicates
    }
}

一旦完成循环,如果您发现了某些内容,请检查循环外部:

   if (printOnce==0) { // nothing was found in the loop 
          // display that nothing was found !  
   }

备注:

直接从文件中读取有限制。它只能用于普通旧数据(POD),而不能使用string成员或包含的更高级类型。为了学习它是一个好的开始,但我建议预见一个Subject成员函数从流中加载数据。当数据结构发展时,这证明更灵活:成员函数可以使用最适合的方式ealsily读取每个成员数据和子对象。

答案 2 :(得分:0)

感谢您的帮助!我设法通过创建一个函数来正确地比较用户输入和结构文件,以便在主题存在与否时检查.dat文件。

int row = checkNumberOfData(fileName);

if (row > 0)
    exist = doesSubjectExist(file, fileName, code);  // checks input 

if (!exist)
{
    file.open(fileName, ios::out | ios::app | ios::binary);

    if (!file)
    {
        cout << "Error opening database..\n"
             << "\tQuitting System ..\n";
        exit(-1);
    }

    strcpy(subjectDB.code, code);

    cout << "Subject Name: ";
    cin.getline(subjectDB.name, MAX);

    cout << "No of assessment tasks: ";
    cin >> subjectDB.num;
    cout << endl;
    .... etc

}