Home > Software design >  Alignment of text while writing and reading a file
Alignment of text while writing and reading a file

Time:07-10

the image is of my console outcome that definitely doesn't seem correct as the total grade holders should be properly printed
the second image is of my text file with last piece of data repeating

    #include<iostream>
    #include<string>
    #include<fstream>
    using namespace std;
    class StudentResult{
        private:
            int sessional;
            int mids;
            int finals;
            int Final_score;
            float percentage;
            char grade;
            string Fname;
            string Lname;
            int counter1=0,counter2=0,counter3=0,counter4=0,counter5=0;
            string str;
            
        public:
            StudentResult(){
                
            }
            void setter()
            {
                cout<<"Enter first name: ";
                cin>>Fname;
                cout<<"Enter Last name: ";
                cin>>Lname;
                cout<<"Enter sessional marks: ";
                cin>>sessional;
                cout<<"Enter mids marks: ";
                cin>>mids;
                cout<<"Enter finals marks: ";
                cin>>finals;
            }
            void calculations()
            {
                Final_score = sessional   mids   finals;
                percentage = (Final_score*100)/100;
                if(percentage>=80 && percentage<=100)
                {
                    grade='A';
                    counter1  ;
                }
                if(percentage>=71 && percentage<80)
                {
                    grade='B';
                    counter2  ;
                }
                if(percentage>=61 && percentage<=70)
                {
                    grade='C';
                    counter3  ;
                }
                if(percentage>=50 && percentage<=60)
                {
                    grade='D';
                    counter4  ;
                }
                if(percentage>=0 && percentage<=49)
                {
                    grade='F';
                    counter5  ;
                }
            
            
                ofstream output;
                output.open("Record.txt", ios::app);
                if(!output)
                {
                    cout<<"Error";
                }
                else
                {
                    output<<Fname<<"\t"<<Lname<<"\t"<<sessional<<"\t"<<mids<<"\t"<<finals<<"\t"<<percentage<<"\t"<<grade<<"\n";
                
                }
                output.close();
                ifstream input;
                input.open("Record.txt");
                if(!input)
                {
                    cout<<"Error";
                    
                }
                else
                {
                    while(!input.eof())
                    {
                        getline(input,str);
                        cout<<str<<endl;
                    }
                    input.close();
                }
                
        }
            void total()
            {
                ofstream output;
                output.open("Record.txt", ios::app);
                output<<"\nTotal number of students who secured A grade: "<<counter1;
                output<<"\nTotal number of students who secured B grade: "<<counter2;
                output<<"\nTotal number of students who secured C grade: "<<counter3;
                output<<"\nTotal number of students who secured D grade: "<<counter4;
                output<<"\nTotal number of students who secured F grade: "<<counter5;
                
        }
                
    };
    int main(){
        StudentResult array[2];
        for(int i=0 ; i < 2 ; i  )
        {
            array[i].setter();
        }
        for(int i=0 ; i < 2 ; i  )
        {
            array[i].calculations();
        }
        
            for(int i=0 ; i < 2 ; i  )
        {
            array[i].total();
        }
      
    }

This is the code I'm working with so basically, I want the information regarding the marks of 2 students, then write the calculated grade, percentage, and the number of students who secured a particular grade onto the file. Next, open the file and print it on the console but it's not doing it in a well-defined fashion like repeating the last process two times of showing the total pupil to secure a particular grade. I hope it makes sense. Help required :)

CodePudding user response:

The problem of seeing repeated lines in the output file comes from this line:

output.open("Record.txt", ios::app);

Record.txt is always being opened in append mode. So if you repeat your tests several times, the writes from previous executions will remain there.

A possible solution for this: make sure you clean the file at the beginning of your program.

int main() {
    std::ofstream output;
    output.open("Record.txt", std::ofstream::out | std::ofstream::trunc);
    output.close();
    ...

Apart from that, there are a few things you may want to check in your program:

  • Counters are member variables. You should turn them into class variables (making them inline static) or globals.
  • Something like a map, pairing grades to counters, would be better than keeping different counters.
  • Final_score and percentage may not need to be member variables. str definitely doesn't.
  • The line (Final_score*100)/100;, will produce an int with the same value as Final_score. Something like (Final_score*10.0f)/100; would produce a float. I don't know if you were after that.
  • You could turn the while(!input.eof()) { getline(input,str); } into while (getline(input, str)) {}.

Here's an example using a std::map for keeping the grade counters. I've also replaced the file stream with string streams.

CodePudding user response:

I made lots of changes in your code and fixed its broken logic to some extent. The rest is your responsibility though I did not make it look too advanced cause there is no need for anything fancy in this case.

Here it is:

#include <iostream>
#include <string>
#include <fstream>
#include <vector>


class Student
{
private:
    std::string firstName { "Unknown" };
    std::string lastName { "Unknown" };
    int sessional { };
    int mids { };
    int finals { };
    int finalScore { };
    float percentage { };
    char grade { '?' };

    inline static int grade_A_count;
    inline static int grade_B_count;
    inline static int grade_C_count;
    inline static int grade_D_count;
    inline static int grade_E_count;
    
public:
    Student( ) = default;

    void setter( )
    {
        std::cout << "Enter the first name: ";
        std::cin >> firstName;
        std::cout << "Enter the last name: ";
        std::cin >> lastName;
        std::cout<<"Enter the sessional marks: ";
        std::cin >> sessional;
        std::cout << "Enter the mids marks: ";
        std::cin >> mids;
        std::cout << "Enter the finals marks: ";
        std::cin >> finals;
    }

    void calculations( const std::string& fileName )
    {
        finalScore = ( sessional   mids   finals ) / 3;
        percentage = static_cast<float>( finalScore );

        if ( percentage >= 80 && percentage <= 100 )
        {
            grade = 'A';
              grade_A_count;
        }
        else if ( percentage >= 70 && percentage < 80 )
        {
            grade = 'B';
              grade_B_count;
        }
        else if ( percentage >= 60 && percentage < 70 )
        {
            grade = 'C';
              grade_C_count;
        }
        else if ( percentage >= 50 && percentage < 60 )
        {
            grade = 'D';
              grade_D_count;
        }
        else if ( percentage >= 0 && percentage < 50 )
        {
            grade = 'F';
              grade_E_count;
        }
        else
        {
        }

        std::ofstream output{ fileName, std::ios::app };

        if ( !output )
        {
            std::cout << "Error\n";
        }
        else
        {
            output << firstName << "\t"
                   << lastName<< "\t"
                   << sessional << "\t"
                   << mids << "\t"
                   << finals << "\t"
                   << '%' << percentage << "\t"
                   << grade << "\n";
        }
    }

    static std::size_t getStudentCount( )
    {
        std::cout << "Enter the students' count: ";
        std::size_t student_count { };
        std::cin >> student_count;

        return student_count;
    }

    static void printFileContents( const std::string& fileName )
    {
        std::ifstream input { fileName };

        if ( !input )
        {
            std::cout << "Error\n";
        }
        else
        {
            std::string line { };
            std::cout << '\n';

            while( !input.eof( ) )
            {
                std::getline( input, line );
                std::cout << line << '\n';
            }
        }
    }

    static void total( const std::string& fileName )
    {
        std::ofstream output { fileName, std::ios::app };

        output << "Total number of students who secured A grade: " << grade_A_count << '\n'
               << "Total number of students who secured B grade: " << grade_B_count << '\n'
               << "Total number of students who secured C grade: " << grade_C_count << '\n'
               << "Total number of students who secured D grade: " << grade_D_count << '\n'
               << "Total number of students who secured F grade: " << grade_E_count << '\n';    
    }
};

int main( )
{
    const std::string fileName { "Record.txt" };
    std::ofstream output { fileName, std::ofstream::trunc };
    output.close( );

    std::vector<Student> students( Student::getStudentCount( ) );

    for ( auto& student : students )
    {
        student.setter( );
    }

    for( auto& student : students )
    {
        student.calculations( fileName );
    }

    Student::total( fileName );

    Student::printFileContents( fileName );
}

Sample input/output:

Enter the students' count: 2
Enter the first name: Kate
Enter the last name: Walker
Enter the sessional marks: 10
Enter the mids marks: 20
Enter the finals marks: 45
Enter the first name: John
Enter the last name: Roberts
Enter the sessional marks: 100
Enter the mids marks: 30
Enter the finals marks: 47

Kate    Walker  10  20  45  % F
John    Roberts 100 30  47  Y D
Total number of students who secured A grade: 0
Total number of students who secured B grade: 0
Total number of students who secured C grade: 0
Total number of students who secured D grade: 1
Total number of students who secured F grade: 1

The number of changes is huge. I don't have the time to sit down and pinpoint them one by one. But they're pretty simple. You can compare your code to the above one and see the changes and improvements.

  • Related