0

I have this assignment for an intro C++ class and I'm confused as to why my getline seems to be working but it doesn't output my functions into the outfile.txt.My teacher said my getline syntax is incorrect, but I'm confused as to how. My infile.txt reads:

T & 4
S @ 6
T x 5
R * 5 7
D $ 7
D + 5
R = 4 3
E

And my code:

#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;


void draw_rect (char out_char, int rows, int columns); // Draws a rectangle shape

void draw_square (char out_char, int rows); //Draws a square shape

void draw_triangle (char out_char, int rows);// Draws a triangle shape

void draw_diamond (char out_char, int rows); // Draws a diamond shape

int main()
{
    ofstream outfile;
    ifstream infile;
    int row, col;
    bool exit = false;
    char value;
    infile.open("infile.txt");
    outfile.open("outfile.txt");
    if(!infile.good())
    {
        cout << "failed to open\n";
    }else
    {
        string buffer;
        while(!infile.eof() || !exit)
        {
            getline(infile, buffer);
                switch(buffer[0])
                {
                case 'R':
                   value = buffer[2];
                   row = buffer[4];
                   col = buffer[6];
                   draw_rect(value, row, col);
                   break;
                case 'T':
                    value = buffer[2];
                    row = buffer [4];
                    draw_triangle(value, row);
                    break;
                case 'D':
                    value = buffer[2];
                    row = buffer[4];
                    draw_diamond(value, row);
                    break;
                case 'S':
                    value = buffer[2];
                    row = buffer[4];
                    draw_square(value, row);
                    break;
                case 'E':
                    cout << "Files Written.\nExiting." << endl;
                    exit = true;
                    break;
                default:
                    cout << "Invalid input, try again" << endl;
                }
        }
    }
    return  0;

}

void draw_diamond (char out_char, int rows)
{
    ofstream outfile;
    int space = 1;
    space = rows - 1;
    for (int i = 1; i <= rows; i++)
    {
        for (int k = 1; k <= space; k++)
        {
            outfile << " ";
        }
        space--;
        for( int k = 1; k <= 2*i-1; k++)
        {
            outfile << out_char;
        }
        outfile << endl;
    }
    space = 1;
    for (int i = 1; i <= rows; i++)
    {
       for(int k = 1; k <= space; k++)
       {
           outfile << " ";
       }
       space++;
       for(int k = 1; k <= 2*(rows-i)-1; k++)
       {
           outfile << out_char;
       }
       outfile << endl;
    }
}

void draw_triangle (char out_char, int rows)
{
    ofstream outfile;
     for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j <= i; j++)
        {
            outfile << out_char;
        }
        outfile << endl;
}
}

void draw_square (char out_char, int rows)
{
    ofstream outfile;
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < rows; j++)
        {
            outfile << out_char;
        }
        outfile << endl;
    }
}

void draw_rect (char out_char, int rows, int columns)
{
    ofstream outfile;
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < columns; j++)
        {
            outfile << out_char;
        }
        outfile << endl;
    }
}
Aux1e
  • 21
  • 3
  • 2
    Sinceraly, strange that your teacher does not point out where is the problem. I simply do not understand how this kind of teaching work. Well. you can't assume that defining an object in main function will magically intialize an object that is defined in a local function. Look at the `draw_diamond` function, how do you expect `ofstream outfile` will be initialized? – Amadeus Mar 16 '19 at 01:56
  • C++ is hard enough to learn, as it is. Utterly incompetent instructors, like the one described here, don't make it any easier. – Sam Varshavchik Mar 16 '19 at 02:12

1 Answers1

3

Using one of your functions as an example:

void draw_rect (char out_char, int rows, int columns)
{
    ofstream outfile;

This declares a new std::ofstream object in your draw_rect() function. draw_rect() does not open this std::ofstream object, so this draw_rect()'s attempts to writing anything into this outfile does absolutely nothing.

The fact that you created an std::ofstream object with the same name in your main(), that you did open, means absolutely nothing. Just because you have the same object with the same name in different functions doesn't mean that they are the same object. C++ does not work this way.

You need to change your main() function to pass its outfile into each function, by reference, as a parameter, instead of declaring another object with the same name in each function. The above function would be, for example:

void draw_rect (ofstream &outfile, char out_char, int rows, int columns)
{

You will need to change each one of your functions to receive the outfile parameter by reference, like that, change their forward declarations, and explicitly pass outfile as a first parameter from main(), in each function call.

Finally, regarding your claim that your teacher told you that there was something wrong with your usage of getline:

You were fully justified with your confusion. If your "getline syntax is incorrect" then you would've gotten a compilation failure. Since your question did not mention any compilation errors, even before investigating and determine the actual issue, it was possible to reasonably conclude that: 1) the getline syntax was correct, 2) the program compiled, and 3) you need to find a better teacher, if your intentions are to actually learn C++ without being hampered by bad instructors.

From all appearances, your issue had nothing to do with getline. Your teacher was simply incompetent, and doesn't really know much about C++. That's not your fault, of course, but you need to understand that.

P.S.:

while(!infile.eof() || !exit)

This is a small bug. In this case the bug is hidden, because eventually exit gets set with your sample input, correctly, but you should fix this after reading and understanding the explanation given at this link.

Sam Varshavchik
  • 84,126
  • 5
  • 57
  • 106
  • I was searching a reference for this bug. Thanks for linking it +1 – Amadeus Mar 16 '19 at 02:08
  • Thanks, good news this program is finally outputting to the outfile thanks to you, but the only problem is the shapes seem to be huge, much larger than their parameters should allow them to be, what am I doing wrong here? `void draw_rect (ofstream &outfile, char out_char, int rows, int columns)` is my function definition and when I call it looks like `draw_rect(outfile, value, row, col);` – Aux1e Mar 16 '19 at 02:28
  • 1
    You are passing this parameter correctly, your program would not compile otherwise. As far as the reason for your huge shapes, it's very simple. For example, you're passing `row = buffer[4];` to `draw_square()`, and your input is `S @ 6`. `buffer` is a `std::string`, and, in this case, its 4th character is `'6'` which is ASCII code 54. Chararacter '6' is ASCII code 54. So you're passing 54 as the number of rows here, which is what you end up drawing, a 54x54 square. You need to open your C++ book, which should explain to you how to convert between characters and integers. – Sam Varshavchik Mar 16 '19 at 02:44
  • Ok I see, so setting `row = buffer[4];` is incorrect for what I'm trying to do, how would I go about just reading that 4th character as an int? Would I use a `static_cast`? and if so would I use that where I set the parameters equal to their buffer values? Also regarding the P.S about the bug, when I change my while loop to either `while (infile >> buffer)` or `while(!infile >> buffer).eof()` it just indefinitely loops my default switch statement, what am I doing wrong here? – Aux1e Mar 16 '19 at 03:15
  • 1
    There should be plenty of different ways of converting character input to `int`s, with many examples in your C++ book. See your C++ book for more information. You should also spend some time learning how to use your debugger, which lets you run your program one line at a time, and examine and inspect the values of all variables as they change. Knowing how to effectively use a debugger is a mandatory skill for every C++ developer. – Sam Varshavchik Mar 16 '19 at 03:19