OK, so I have this program I am writing called 'GradeBook', and there is a problem that starting on int Menu1(), ' if (menuchc == "4") ', and ending

if (menuchc == "y", "Y")
{
     string tmp = "start " + po;
     system(tmp.c_str());
     system("pause");
     main();
                 }

so, I've come to conclude that getline() is not reading correctly, and subsequently tmp is null, and so substr() is throwing out_of_bounds. can someone help please? thanks!

here's the code:

/*
  Name: GradeBook 2010
  Copyright: Steven Talarman, 2009-2010
  Author: Steven Talarman
  Date: 12/01/10 16:52
  Description: A Grade Book.
  Comments: Please note that fcdel.exe and GradeBook.exe MUST be in the same directory. Same as with
  every .XQS file.
*/

#include <fstream>
#include <cmath>
#include <windows.h>
#include <time.h>
#include <string>
#include <iostream>

#define cls system("cls");

using namespace std;
// Declarations

// Variables

int ntt;
int gte; //go to exit
int nsa; // name shown already
bool tto; //title turned off
bool pea; //password entered already
int ic; //if closed
char sdate[9];
char stime[9];
int resetd;
int numot; //number of tries
int nos; // number of seconds
string teachname;
string inassn;
string password;
string tempname;
string rot; //reset or try again
int ranalready; //if run once was set up
string assnnams[9995];
string assnddates[9995];
int ifttl = 0; // if title (MakeTitle()) was already called
string menuchc;
string temppass;
int hldfr;
string assnname;
char duedate[12];
char runonce[] = { "RODAT.XQS" }; //Run Once Data.xqs
char passfile[] = { "QALDAT.XQS" }; //Password File
char sysdat[] = { "SYSDAT.XQS" };
char icwc[] = { "CLESDAT.XQS" };
char logassns[] = { "XCAPLODAT.XQS" };
char tempsysdat[] = { "VISLODAT.XQS" };
char tempassns[] = { "SHOLJDAT.XQS" };
char temprunonce[] = { "CVNSHDAT.XQS" };
char temppassword[] = { "SXHTUDAT.XQS" };
string _tempsysdat;
string _tempassns;
string _temprunonce;
string _temppassword;
// End Variables
// Functiions
DWORD APIENTRY UpdateTime(LPVOID lpParam);
int MakeFiles();
int RunOnce();
int Security();
int MakeTitleScreen();
int DrawMenu();
int MakeTitle();
int GetSysDate();
int ClrScrn() {system("cls");}
int LogAssn();
int ShowCredits();
int GetChc();
int CompareChoice();
int NewAssaignment();
int Menu0();
int Menu1();
int Menu2();
int Menu3();
int Menu4();
int Menu5();
int Menu6();
int GetAverage();
// End Functions
// Classes
struct ThreadWrap
{
       int waste;
       } Wrap[5];
// End Classes
//End of Declarations

DWORD APIENTRY UpdateTime(LPVOID lpParam)
{
      {
      char time[9], date[9];
      _strdate(date);
      string tim, tmp;
      int ab;
      while (1)
      {
            _strtime(time);
            tmp = string(time);
            if (tmp.substr(0, 2) <= "11")
            {
                              ab = atoi(tmp.substr(0, 2).c_str());
                              ab++;
                               tim = "title GradeBook - Active Session: " + teachname + " " + string(date) + " " + tmp + " AM";
                               system(tim.c_str());
                              }
            if (tmp.substr(0, 2) == "12" || "00")
            {
                              if (tmp.substr(0, 2) == "12")
                              {
                              tim = "title GradeBook - Active Session: " + teachname + " " + string(date) + " " + "12" + tmp.substr(2, 7) + "PM";
                              system(tim.c_str());       
                              }
                              if (tmp.substr(0, 2) > "12")
                              {
                              tim = "title GradeBook - Active Session: " + teachname + " " + string(date) + " " + "12" + tmp.substr(2, 7) + "AM";
                              system(tim.c_str());
                              }        
                              }
            else
            {
            ab = atoi(tmp.substr(0, 2).c_str());
            tim = "title GradeBook - Active Session: " + teachname + " " + string(date) + " " + string(time);
            system(tim.c_str());
            }
            }
      }
      }
      DWORD dwParm;
      HANDLE handle = CreateThread(NULL, 0, &UpdateTime, &Wrap[0], 0, &dwParm);
int MakeFiles()
{
ofstream Set1 (sysdat, ios::app);
Set1 << "";
ofstream Set2 (icwc, ios::app);
Set2 << "";
ofstream Set3 (runonce, ios::app);
Set3 << "";
ofstream Set4 (passfile, ios::app);
Set4 << "";
ofstream Set5 (logassns, ios::app);
Set5 << "";
ofstream Set6 (tempsysdat, ios::app);
Set6 << "";
ofstream Set7 (tempassns, ios::app);
Set7 << "";
ofstream Set8 (temprunonce, ios::app);
Set8 << "";
ofstream Set9 (temppassword, ios::app);
Set9 << "";
 }

int RunOnce()
{
                   ranalready = 1;
                   cout << "Enter your name: ";
                   getline(cin, teachname);
                   cout << "Enter the password you wish to use: ";
                   getline(cin, password);
                   ofstream RanSetTrue (runonce, ios::out);
                   RanSetTrue << ranalready << endl << teachname << endl << password << endl;
                   ofstream RanSetTrue_temp (temprunonce, ios::out);
                   RanSetTrue_temp << ranalready << endl << teachname << endl << password << endl;
                   ofstream StreamPass (passfile, ios::out);
                   StreamPass << password;
                   cls
                   system("title GradeBook - Active Session");
                   cout << "Done. You account has been set up.\nThank you, " << teachname << ".\n";
                   system("title Thank you. Please Press any key to continue.");
                   system("pause");
                   char tdate[9], ttime[9];
                   _strdate(tdate);
                   _strtime(ttime);
                   string title = "title GradeBook - Active Session: " + teachname + " " + string(tdate) + " " + string(ttime);
                   system(title.c_str());

}
int main()
{
    cls
    top:
    system("color 1F");
    if (gte == 0) {
    Security();
}
if (gte != 0) 
{
        cls
        while (1)
        {
              throw (passfile);
        }
    }
}

int Security()
{
    if (ranalready != 1) {
    ifstream GetRunOnceInfo (runonce, ios::in);
    GetRunOnceInfo >> ranalready;
    getline(GetRunOnceInfo, teachname);
    getline(GetRunOnceInfo, teachname);
    getline(GetRunOnceInfo, password);
    //ifstream GetPass (passfile, ios::in);
    //GetPass >> password;
}
    if (ifttl == 0) {//2
    MakeTitleScreen();
    main();
}//1
      if (ranalready == 0)
    {//2
                   RunOnce();
                   main();
                   }//1
                   if (ranalready != 0) {//2
    cls
    goto place1;
}//1
        

place1:
       if (pea == true) 
       {
               goto gomenu;
               }
       if (pea != true){
       
if (ifttl != 0) { //2
int igt; //if gone thru
          if (numot < 10)
          { //3
          igt++;
          if (pea == false) {
          cout << "Enter your password, " << teachname << ": ";
          cin >> temppass;
          } else { goto gomenu; }
          
          if (temppass != password) { //4 
                       cls
                       numot++;
                       cout << "That was incorrect; please try again.";
                       if (numot == 10)
                       { //5
                                 goto gtt;
                                 } //4 
                                 if (numot < 10) {//5
                       cout << "\nYou have tried " << numot << " times. you have " << 10 - numot << " tries left.";
                       } //4
                       cout << endl;
                       system("pause");
                       main();
                       } //3
                       if (temppass == password) {//4
                       gomenu:
                            cls
                            char tdate[9], ttime[9];
                            _strdate(tdate);
                            _strtime(ttime);
                            string tim, time;
                            tim = string(ttime);
                            if (atoi(tim.substr(0, 2).c_str()) > 12)
                            {/*time = atoi(itoa(0, tim.substr(0, 2).c_str(), strlen(tim.substr(0, 2).c_str()))) + tim.substr(2, 7);*/}
                            string title = "title GradeBook - Active Session: " + teachname + " " + string(tdate) + " " + time;
                            system(title.c_str());
                            pea = true;
    DrawMenu();
    CompareChoice();
    } //3
                       if (numot > 10) { //4
                       gtt:
                            cls
                             ofstream oBupSysdat;
                                    ofstream Frmt1 (tempsysdat, ios::out);
                                    Frmt1 << "";
                                    oBupSysdat.open(tempsysdat, ios::out);
                                    ifstream iBupSysdat(sysdat, ios::in);
                                    while (!iBupSysdat.eof())
                                    {
                                          getline(iBupSysdat, _tempsysdat);
                                          oBupSysdat << _tempsysdat << endl;
                                          }
                                    oBupSysdat.close();
                                    iBupSysdat.close();
                                    //
                                    ofstream oBupAssn;
                                    ofstream Frmt2 (tempassns, ios::out);
                                    Frmt2 << "";
                                    oBupAssn.open(tempassns, ios::out);
                                    ifstream iBupAssn(logassns, ios::in);
                                    while (!iBupAssn.eof())
                                    {
                                          getline(iBupAssn, _tempassns);
                                          oBupAssn << _tempassns << endl;
                                          }
                                    oBupAssn.close();
                                    iBupAssn.close();
                                    //
                                    ofstream oBupRunOnce;
                                    ofstream Frmt3 (temprunonce, ios::out);
                                    Frmt3 << "";
                                    oBupAssn.open(temprunonce, ios::out);
                                    ifstream iBupRunOnce(runonce, ios::in);
                                    while (!iBupRunOnce.eof())
                                    {
                                          getline(iBupRunOnce, _temprunonce);
                                          oBupRunOnce << _temprunonce << endl;
                                          }
                                    oBupRunOnce.close();
                                    iBupRunOnce.close();
                                    //
                                    ofstream oBupPass;
                                    ofstream Frmt4 (temppassword, ios::out);
                                    Frmt4 << "";
                                    oBupPass.open(temppassword, ios::out);
                                    ifstream iBupPass(passfile, ios::in);
                                    while (!iBupPass.eof())
                                    {
                                          getline(iBupPass, _temppassword);
                                          oBupPass << _temppassword << endl;
                                    }
                                    /*
                                    end backup sequence
                                    -[|---------|---------|]-
                                    format sequence 
                                    */
                                    ofstream DelSysdat (sysdat, ios::out);
                                    DelSysdat << "";
                                    ofstream DelAssn (logassns, ios::out);
                                    DelAssn << "";
                                    ofstream DelRunonce (runonce, ios::out);
                                    DelRunonce << "";
                                    ofstream DelPass (passfile, ios::out);
                                    DelPass << "";
                                    nos = 30;
                            while (nos > 0) { //5
                            cout << "You have exceeded the maximum number of tries9.\n\nThe application will completely erase all data in: " << nos;
                            Sleep(1000);
                            nos--;
                            cls
                            } //4
                            rot = "R";
                            if (rot == "R", "r", "reset")
                            { //5                            
                           
                                    resetd = 1;
                                    cout << "Reset. Press any key to close the application.";
                                    system("pause>nul");
                                    system("start GradeBook.exe");                
                                                   
                                                   
                                                                                                          }
                                     
                       
          }//3
                       }//2    
                       }//1


}//00
}
    

int MakeTitleScreen()
{
    cout << "\n\n\n\t\t\t\t GradeBook 2010";
    cout << "\n\n\t\t\t\t  Produced by:\n\n\t\t\tSkyNoteSolutions::SkyNoteMusic, OPB.";
    if (hldfr != 1) {
    cout << "\n\n\n\n\n\n\n\t\t\t  Performing Startup Operations...\n\n\n\n";
}
else {
     cout << "";
     }
    if (hldfr == 0)
    {
    cout << "\n\t\t\t\t\n\n\t\t\t    (c) 2010 Stephen Talarman";
        MakeFiles();
    MakeTitle();
    Sleep(2250);
}
if (hldfr != 0)

{
          cout << "\n\t\t\t\t\n\n\t\t\t    (c) 2010 Stephen Talarman";
          system("pause>nul");
              MakeFiles();
    MakeTitle();
          }
    cls
    ifttl = 1;
 }


int MakeTitle()
{
     system("title GradeBook");
 }

int GetSysDate()
{
char sdate[9];
char stime[9];
_strdate(sdate);
_strtime(stime);
 }

int DrawMenu()
{
     cls
     if (gte == 1)
     {
             main();
             }
             else {
     cout << "1.) Assignments\n2.) Grades\n3.) Attendence\n4.) Statistics\n5.) Settings / Options\n6.) More: ";
     GetChc();
 }
}
 
int ShowCredits()
  {
       ifttl = 0;
       hldfr = 1;
       main();
   }
   
int GetChc() {
cin >> menuchc;
}

int CompareChoice()
{
    if (menuchc == "0") {
                gte = 1;
                }
    if (menuchc == "1") {
                cls
                Menu1();
                            }
    if (menuchc == "2") {
                cls
                Menu2();
                }
    if (menuchc == "3") {
                cls
                Menu3();
                }
    if (menuchc == "4") {
                cls
               Menu4();
                }
    if (menuchc == "5") {
                cls
              Menu5();
                }
    if (menuchc == "6") {
                cls
               Menu6();
                }
    if (menuchc == "credits")
    {
                ShowCredits();
                }
    if (menuchc == "help")
    {
                cls
                cout << "Soon to come";
                Sleep(3000);
                main();
                }
    if (menuchc == "reset") {
                cls
                ifttl = 0;
                hldfr = 1;
                main();
                }
    if (menuchc == "exit")
    {
                gte = 1;
                main();
                }
    if (menuchc == "32")
    {
                ofstream ClrBup (tempassns, ios::out);
                ClrBup << "";
                cls
                main();
                }
    if (menuchc != "0", "1", "2", "3", "4", "5", "6", "7", "32", "credits", "help", "reset", "exit")
    {
                if (gte == 0)
                {
                cls
                cout << "Your selection is not valid. Please try again.\n\n\n\n";
                system("pause");
                cls
                main();
                }
                else {
                     cls
                     main();
                     }
                }
                }
int Menu0()
{
     gte = 1;
     main();
}
int Menu1() 
{
    cout << "1.) New Assignment\n2.) Assignment History\n3.) Clear History\n4.) Export data to Excel format\n5.) Access Files: ";
    cin >> menuchc;
    if (menuchc == "1") {
                
                cls
                cout << "Enter the new assignment's name: ";
                getline(cin, assnname);
                getline(cin, assnname);
                if (assnname == "0")
                {
                             main();
                             }
else {
                cout << "Enter the due date: ";
                cin >> duedate;
                ofstream NewAssn (logassns, ios::app);
                NewAssn << "Assignment Name: " << assnname << "\n" << "Due on: " << duedate << "\n" << "Assigned on: " << _strdate( sdate ) << "\n" << "At: " <<  _strtime( stime ) << "\n____________________________________________________________\n";
                ofstream BupAssn (tempassns, ios::app);
                BupAssn << "Assignment Name: " << assnname << "\n" << "Due on: " << duedate << "\n" << "Assigned on: " << _strdate( sdate ) << "\n" << "At: " <<  _strtime( stime ) << "\n____________________________________________________________\n";
                cout << "Saved.\n";
                system("pause");
                }
}
if (menuchc == "2") {
            cls
            cout << "Assignment History:\n____________________________________________________________\b\b";
            ifstream infl;
            infl.open(logassns, ios::in);
            while (!infl.eof())
            {
                  getline(infl, inassn);
                  cout << inassn << endl;
                  }
                  infl.close();
                  system("pause>nul");
            }
            if (menuchc == "3") {
                        cls
                        string yon;
                        cout << "Are you sure you want to delete the assignment history? (Y/N) ";
                        tryagain:
                        while (!GetAsyncKeyState(0x59))
                {
                      Sleep(10);
                      if (GetAsyncKeyState(0x4E))
                      {
                                                  cls
                             cout << "Not Deleted.\n";
                             system("pause");
                             main();
                                                 }
                                                 if (GetAsyncKeyState(0x59))
                                                  {
                        ofstream ClearAssn (logassns, ios::out);
                        ClearAssn << "";
                        cls
                        cout << "Done.\n";
                        system("pause");
                        main();    
                        }
                        }
                        }
                        if (menuchc == "4")
                        {
                                    #define l system("pause");
                                    string po, log;
                                    system("cls");
                                    cout << "Enter the name you wish for your file: ";
                                    cin >> po;
                                    po += ".csv";
                                    //
                                    ofstream SavCsv(po.c_str(), ios::out);
                                    ifstream InCsv;
                                    InCsv.open(logassns);
                                    string tmp;
                                    SavCsv << "Assignment Name,Due Date,Assigned On, Assinged At";
//BupAssn << "Assignment Name: " << assnname << "\n" << "Due on: " << duedate << "\n" << "Assigned on: " << _strdate( sdate ) << "\n" << "At: " <<  _strtime( stime ) << "\n____________________________________________________________\n";
                                    if (InCsv.is_open())
                                    {
                                    while (!InCsv.eof())
                                    {
                                    getline(InCsv, tmp);
                                    getline(InCsv, tmp);
                                    int pos = tmp.find("Assignment Name: ");
                                    cout << tmp;
                                    /*
                                     * Error occures, that tmp is not having a value assigned.
                                     */
                                    l
                                    SavCsv << tmp.substr(pos, strlen(tmp.c_str())) << ",";//14
                                    l
                                    pos = tmp.find("Due on: ");
                                    l
                                    SavCsv << tmp.substr(pos, strlen(tmp.c_str())) << ",";//8
                                    l
                                    pos = tmp.find("Assaigned on: ");
                                    l
                                    SavCsv << tmp.substr(pos, strlen(tmp.c_str())) << ",";//14
                                    l
                                    pos = tmp.find("At: ");
                                    l
                                    SavCsv << tmp.substr(pos, strlen(tmp.c_str())) << endl;//4
                                    l
                                    }
                                    InCsv.close();
                                    }
                                    cout << "Done. Would you like to open it? (Y/N) ";
                                    cin >> menuchc;
                                           if (menuchc == "y", "Y")
                                           {
                                                       string tmp = "start " + po;
                                                       system(tmp.c_str());
                                                       system("pause");
                                                       main();
                                                       }
                                           else
                                           {
                                               main();
                                           }
                                    
                                    //
                                    }
                                  else
                                  {
                                      main();
                                  }                        
            }

int Menu2() {
    cls
    cout << "1.) View By Student\n2.) View By Class\nView By Letter Grade: ";
    cin >> menuchc;
    if (menuchc == "0") {
            main();
            cout << "test";
            system("cls");
            }
}

int Menu3() {
    if (menuchc == "0") {
                
            main();
            }
}

int Menu4() {
if (menuchc == "0") {
            main();
            }
}

int Menu5() {
    if (menuchc == "0") {
            
            }
            
            
}

int Menu6() {
    string tmpa;
    mm6:
    cls
    cout << "1.) Back - Up\n2.) Edit Preferences\n3.) Program Options: ";
    cin >> tmpa;
    if (tmpa == "1")
    {
                cls
                cout << "This will completely restore all data. Proceed? (Y/N) ";
                while (!GetAsyncKeyState(0x59))
                {
                      Sleep(10);
                      if (GetAsyncKeyState(0x4E))
                      {
                                                 cls
                                                 main();
                                                 }
                                                 else {Sleep(05);}
                      }
                cls
                cout <<"Starting...";
                //back - up sequence
                                     cout << "\nReading System Data...";
                                    ofstream oResSysdat;
                                    oResSysdat.open(sysdat, ios::out);
                                    ifstream iResSysdat(tempsysdat, ios::in);
                                    cout << "\nRestoring previous system data...";
                                    while (!iResSysdat.eof())
                                    {
                                          getline(iResSysdat, _tempsysdat);
                                          oResSysdat << _tempsysdat << endl;
                                          }
                                    oResSysdat.close();
                                    iResSysdat.close();
                                    cout << " Done.";
                                    //
                                    cout << "\nReading Assignments...";
                                    ofstream oResAssn;
                                    oResAssn.open(logassns, ios::out);
                                    ifstream iResAssn(tempassns, ios::in);
                                     cout << "\nRestoring Assignments...";
                                    while (!iResAssn.eof())
                                    {
                                          getline(iResAssn, _tempassns);
                                          oResAssn << _tempassns << endl;
                                          }
                                    oResAssn.close();
                                    iResAssn.close();
                                    cout << " Done.";
                                    //
                                    cout << "\nReading Run Once Data...";
                                    ofstream oResRunOnce;
                                    oResRunOnce.open(runonce, ios::out);
                                    ifstream iResRunOnce(temprunonce, ios::in);
                                    cout << "\nRestoring Run Once Data...";
                                    while (!iResRunOnce.eof())
                                    {
                                          getline(iResRunOnce, _temprunonce);
                                          oResRunOnce << _temprunonce << endl;
                                          }
                                    oResRunOnce.close();
                                    iResRunOnce.close();
                                    cout << " Done.";
                                    //
                                    cout << "\nReading Account Data / Settings...";
                                    ofstream oResPass;
                                    oResPass.open(passfile, ios::out);
                                    ifstream iResPass(temppassword, ios::in);
                                    cout << "\nRestoring Account Data / Settings...";
                                    while (!iResPass.eof())
                                    {
                                          getline(iResPass, _temppassword);
                                          oResPass << _temppassword << endl;
                                    }
                                    iResPass.close();
                                    oResPass.close();
                                    cout << " Done.";
                                    //
                                    cout << "\nRestored. Would you like to restart the application\n(recommended)? (Y/N) ";
                                     while (!GetAsyncKeyState(0x59))
                {
                      Sleep(10);
                      if (GetAsyncKeyState(0x4E))
                      {
                                                 cls
                                                 main();
                                                 }
                                                 else {Sleep(05);}
                      }
                                             system("start GradeBook.exe");
                                             gte = 1;
                                             main();
                                             }
                                             
                                             /* else {
                                                  cls
                                                  main();
                                                  }*/
    else if (tmpa == "0") {
            main();
            }
    else if (tmpa == "2")
    {
                cls
                cout << "1.) Edit Account Info\n2.) Edit Colors: ";
                cin >> menuchc;
                if (menuchc == "1")
                {
                            cls
                }
                main();
                }
    else if (tmpa == "3")
    {
         cls
         if (tto == false)
         {
               cout << "1.) Turn off time updating in title: ";
               cin >> tmpa;
               if (tmpa == "1")
                {
                           cout << "This will Turn off time updating in the title. Proceed? (Y/N) ";
                           cin >> tmpa;
                           if (tmpa == "y", "Y")
                           {
                                    tto = true;
                                    SuspendThread(handle);
                                                 cout << "Done.\n";
                                                 char tdate[9];
                                                 _strdate(tdate);
                                                 string title = "title GradeBook - Active Session: " + teachname + " " + string(tdate);
                                                 system(title.c_str());
                                                 cout << "Press any key to continue . . .";
                                                 system("pause>nul");
                                                 main();
                                    }
                           else
                           {
                               main();
                           }
                           }
                           }
                else
                {
                 cout << "1.) Turn on time updating in title: ";
               cin >> tmpa;
               if (tmpa == "1")
                {
                           cout << "This will Turn on time updating in the title. Proceed? (Y/N) ";
                           cin >> tmpa;
                           if (tmpa == "y", "Y")
                           {
                                    tto = false;
                                    ResumeThread(handle);
                                                 cout << "Done.\n";
                                                 cout << "Press any key to continue . . .";
                                                 system("pause>nul");
                                                 main();
                                    }   
                }
                           }
               }
               else {
                           main();
                           }
}

Recommended Answers

All 6 Replies

Line 628 is not the right syntax:

if (menuchc == 'y' || menuchc == 'Y')

I think that's the least of your worries though. This is quite a, er, creative program. There are a lot of constructs here (goto and calling main explicitly) along with a lot of non-standard stuff that will take away any portability.

Yes, the code is very... terrible. I have to close by throwing an error, because I've called main too many times, and returning main() goes back to the calling function T.T

Do you have a good text to follow? It's not so good to develop bad habits early on as they will stick with you. Even looking around at (a majority) of the code on this site should give you some idea and there's countless examples of menuing systems.

Functions should be called and the value returned and then called again if necessary later on. They shouldn't be an entry point into the spider's web.

I'm not trying to be harsh here, btw, just trying to help you use what you have to make a much more effective program.

I appreciate all comments / criticism alike. And I agree with you, if I had to write this over again, the menu system would be FAR more efficient. This is early code that I've 'outgrown', but still pursuing, and I want to try and get the getline() problem fixed.

Try to cout tmp on both 601 and 602. Make sure the file is opening and you're actually inside the while loop. If it's not opening check the file itself and make sure it's in the right directory (one way to check is to write out a file to the same directory and manually make sure it's there).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.