1

I'm doing a lab for my C++ class in school. The program reads binary numbers in from a file, then calculates their decimal equivalent and prints them to the console, but it has to read the entire file in character by character. The program is supposed to ignore leading spaces and 0s. When the program reaches an invalid digit, I want it to backspace to the beginning of the line, then indent and print out the message "Bad digit on input" like so:

enter image description here

All of the "Bad digit input" should be left aligned with the rest of the numbers in the Binary Number column, but as you can see...

Console output

Here is the entire program:

int main(void)
{
    //Declarations
    ifstream infile;
    char x = 0;
    int y = 0, i = 0, count = 0, q = 0, l = 0;
    //Prints out header to console
cout << left << setw(20) << "Binary Number" << right << setw(15) << "Decimal Equivalent" << endl;

//Opens data file
infile.open("INLABVII.dat");

//Will loop through file until it reaches <eof>
while(!infile.eof())
{
    //Gets character from file
    infile.get(x);

    //Digit is a valid binary digit
    if(x == '1' || x == '0')
    {
        //First binary digit read in
        if(y == 0)
        {
            //Backspace any leading spaces or zeros
            for(i = 0; i < count; i++)
            {
                cout << '\b';
            }

            //Add 6 spaces to indent line
            for(q = 0; q < 6; q++)
            {
                cout << " ";
                count++;
            }
            if (x == '1')       //First digit was a 1
            {
                y = y*2+1;
                cout << "1";
                count++;
                l++;
            }else               //First digit was a 0
            {
                y = y*2;
                cout << "0";
                count++;
                l++;
            }
        }else if(y != 0)
        {
            if (x == '1')       //Digit was a 1
            {
                y = y*2+1;
                cout << "1";
                count++;
                l++;
            }else               //Digit was a 0
            {
                y = y*2;
                cout << "0";
                count++;
                l++;
            }
        }
    }else if(x == ' ')          //Read in a space
    {
        if(y == 0)              //Was a leading space
        {
            count++;
        }else if(y != 0)        //Now testing for if it is a space at the end of the line
        {
            //Gets character from file
            infile.get(x);

            if(x == '\n')       //Space was at the end of the line
            {
                cout << right << setw(15) << y << endl;
                y = 0;
                count = 0;
            }else               //Space was either in the middle of the number, or there was more than one at the end of the line
            {
                //Backspace to beginning of current line on console
                for(i = 0; i < count; i++)
                {
                    cout << '\b';
                }

                //Add 6 spaces to indent line
                for(q = 0; q < 6; q++)
                {
                    cout << " ";
                    count++;
                }
                cout << left << setw(25) << "Bad digit on input" << endl;
                y = 0;
                count = 0;

                //Skip to next line if infile has invalid digit on current line
                infile.ignore(100, '\n');   //Skip bad input
            }
        }
    }else if (x == '\n')        //End of line
    {
        cout << right << setw(15) << y << endl;
        y = 0;
        count = 0;

    }else if(x != '1' && x != '0' && x != ' ' && x != '\n')     //Invalid digit was read in
    {

        //Backspace to beginning of current line on console
        for(i = 0; i < count; i++)
        {
            cout << '\b';
        }

        //Print out 6 spaces to indent line
        for(q = 0; q < 6; q++)
        {
            cout << " ";
            count++;
        }
        cout << left << setw(25)<< "Bad digit on input" << endl;
        y = 0;
        count = 0;

        //Should skip to next line if infile has invalid digit on current line
        infile.ignore(100, '\n');   //Skip bad input


    }

}

return 0;
}

Here is what I have in my input file (I substituted _ for " " so they would be visible):

Input file

From what I know, looping cout << '\b'; a certain number of times should backspace that number of characters, but for some reason mine is not.

Edit: Added cout << '\r';. Here is my new output. Now I have random blank lines and the input with leading zeros still does not print out correctly.

enter image description here

Edit: Fixed the leading zero problem. Adding cout << '\r'; just moved "Bad digit on input" to the next line, leaving the already printed characters on the line above.

enter image description here

  • 1
    Offish topic: `while(!infile.eof())` won't work that well for you. More here: http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong – user4581301 Nov 25 '16 at 03:13
  • 1
    It is generally easier to not write stuff in the first place than clean up the console afterwards. Hold onto your output until you know you want to write it, then write it. – user4581301 Nov 25 '16 at 03:16
  • `while(infile.get(x))` hasn't been covered in class? Odd. I see both `while` and `infile.get(x)` in your code. – user4581301 Nov 25 '16 at 03:23
  • For this assignment we can't hold onto the output. We have to output each digit as it is read in. I originally had that, but then it wouldn't read the last line of the file – joe_Mclovin Nov 25 '16 at 03:24
  • I changed the `while(!infile.eof())` to `while(infile.get(x))` and it got rid of the extra 0. I didn't read the entire post through before I said that I had to use `while(!infile.eof())`. – joe_Mclovin Nov 25 '16 at 03:46

2 Answers2

1

You can try to use a combination of backspace \b and space like so:

// Delete the last character
std::cout << "\b \b" << std::flush;

// Delete the last two characters
std::cout << "\b\b  \b\b" << std::flush;

The expression goes back a number of characters, overwrites with space what is already written, and again goes back to the new output position.

To go back to the beginning of the line, use \r. You will have to overwrite everything which is already written to the current line.

maij
  • 3,604
  • 1
  • 10
  • 26
1

The problem has something to do with MacOS. I tried backspacing fixed input and nothing was deleted even when I just output '\b'. I ran my program in Visual Studio and it outputs as expected, so I have concluded that either Eclipse on MacOS or MacOS itself does not support '\b'.