C++ noob needs guidance

Hello,

First of all I am new to this forum and am grateful for its presence. I am stuck starting a new course as I am so close to graduating with my AA in Computer Networking.

Here is the assignment. I am NOT asking for the answer but I do need guidance on how to be able to complete it. I have spent numerous hours trying to complete it but I have been unsuccessful.




Here is the assignment guidlines. below you can see what I have been able to do so far.

The format of the PGM image file you’ll create is described here: http://en.wikipedia.org/wiki/Netpbm_format#PGM_example

The image must:
be at least 300 pixels wide by 200 pixels tall (and NOT square)
consist of grayscale values from 0 to 255
contain at least two rectangles
contain at least two circles.

Your program’s main will declare the array, then call the following two functions (which you’ll write):
void createImage(unsigned char image[][WIDTH], int height );
bool writeImage(const unsigned char image[][WIDTH], int height, const string fileName );

The createImage() function will create all the image’s pixel values. It must make use of the following function (which you’ll write)
void drawrect(unsigned char image[][WIDTH], int imgHeight,
int rectTop, int rectLeft, int rectHeight, int rectWidth, unsigned char grayLevel);

And to have the possibility of getting an A:
void drawcircle(unsigned char image[][WIDTH], int height,
int centerX, int centerY, int radius, unsigned char grayLevel)

The writeImage() function will write the array data to the specified text file (along with the necessary header lines).


Here is my answer that I have been able to accomplish so far....



#include <iostream>
#include <fstream> //for file I/O
using namespace std;

const int WIDTH = 300;
const int HEIGHT = 200;


void initialize(unsigned char img[][WIDTH]) {
for (int row = 0; row < HEIGHT; row++)
for (int col = 0; col < WIDTH; col++)
img[row][col] = 255;
}



void drawRect(unsigned char image[][WIDTH], int imgHeight,
int rectTop, int rectLeft, int rectHeight, int rectWidth, unsigned char grayLevel)
{


}


void drawCircle(unsigned char image[][WIDTH], int height,
int centerX, int centerY, int radius, unsigned char grayLevel) {

}

void createImage(unsigned char image[][WIDTH], int height) {

}

bool writeImage(const unsigned char image[][WIDTH], int height, const string fileName) {
ofstream imgFile;

imgFile.open("picture.txt");

for (int row = 0; row < HEIGHT; row++) {
for (int col = 0; col < WIDTH; col++)
imgFile << static_cast<int>(img[row][col]) << ' ';
imgFile << '\n';
}

imgFile.close();
}


//=============================================================
int main()
{
unsigned char img[HEIGHT][WIDTH];

initialize(img);
drawRect(img);
writeImage(img);

return 0;
}


The troubles I am having is I do not know how to put in 2 rectangles, the grayscale values from 0 to 225, and if possible I would like to know how to make it contain 2 circles.

In advance I am grateful for any assistance you all may have with assisting me as I am getting familiar with C++. Thanks for having me as a member on this site. I am looking forward to learning a lot from you all.

Regards,

Nana
Take some grid paper and draw out the required images. Circles and squares. Use that as the basis for your your pixel data.
Here is a start showing how the screen is mapped and initialized and how to draw a rectangle - as many rectangles as you (later) want.

The principle at work is the array is initialized, then the rectangle is inserted into the array, all hidden. Then finally the array is cout'ed ie drawn to the screen.

(Once you get that going you will see that the gray level can also be considered as a third dimension to add to the existing 2D array or a parallel separate 2D array of integers (or bytes) (0-255) )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>

using namespace std;

const int WIDTH = 20; // <-- START SMALL
const int HEIGHT = 10;

void initialize(unsigned char img[][WIDTH]);
void drawImage(unsigned char img[][WIDTH]);
void drawRect(
              unsigned char img[][WIDTH],
              int rectTop, int rectLeft,
              int rectHeight, int rectWidth,
              unsigned char grayLevel
              );

int main()
{
    unsigned char img[HEIGHT][WIDTH];
    
    initialize(img);
    
    drawRect(img, 1, 2,  3, 5,  '7');
    drawImage(img);
    return 0;
}

void initialize(unsigned char img[][WIDTH])
{
    for (int row = 0; row < HEIGHT; row++)
    {
        for (int col = 0; col < WIDTH; col++)
        img[row][col] = '.';
    }
}

void drawImage(unsigned char img[][WIDTH])
{
    for (int row = 0; row < HEIGHT; row++)
    {
        for (int col = 0; col < WIDTH; col++)
        {
            cout << img[row][col];
        }
        cout << '\n';
    }
    cout << '\n';
}

void drawRect(
              unsigned char img[][WIDTH],
              int rectTop, int rectLeft,
              int rectHeight, int rectWidth,
              unsigned char grayLevel
              )
{
    // TOP
    for(int col = rectLeft; col <= rectLeft + rectWidth; col++)
    img[rectTop][col] = grayLevel;
    
    // BOTTOM
    for(int col = rectLeft; col <= rectLeft + rectWidth; col++)
    img[rectTop + rectHeight][col] = grayLevel;
    
    // RHS
    for(int row = rectTop; row <= rectTop + rectHeight; row++)
    img[row][rectLeft + rectWidth] = grayLevel;

    // LHS
    for(int row = rectTop; row <= rectTop + rectHeight; row++)
    img[row][rectLeft] = grayLevel;
}



....................
..777777............
..7....7............
..7....7............
..777777............
....................
....................
....................
....................
....................

Program ended with exit code: 0
Hello NanaM,

Sorry I found this so late. Since you are new here some tips to help:


PLEASE ALWAYS USE CODE TAGS (the <> formatting button), to the right of this box, when posting code.

Along with the proper indenting it makes it easier to read your code and also easier to respond to your post.

http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/

Hint: You can edit your post, highlight your code and press the <> formatting button. This will not automatically indent your code. That part is up to you.

You can use the preview button at the bottom to see how it looks.

I found the second link to be the most help.


I noticed that you are using 2 different styles of {}s. Either style is fine, but pick 1 and be consistent in its use. It does make the code easier to read.

Have a look at: https://en.wikipedia.org/wiki/Indentation_style#Brace_placement_in_compound_statements

The first example says "K&R, Allman", but it is more the "Allman" style and the last example is more the original "K&R" style.

Personally I find the "Allman" style the easiest to read.

The code that you posted did not compile for me. The comments in the following code should help.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <fstream> //for file I/O

using namespace std;

const int WIDTH = 300;
const int HEIGHT = 200;

void initialize(unsigned char img[][WIDTH])
{
    for (int row = 0; row < HEIGHT; row++)
        for (int col = 0; col < WIDTH; col++)
            img[row][col] = 255;
}

void drawRect(unsigned char image[][WIDTH], int imgHeight,
              int rectTop, int rectLeft, int rectHeight, int rectWidth, unsigned char grayLevel)
{


}

void drawCircle(unsigned char image[][WIDTH], int height,
                int centerX, int centerY, int radius, unsigned char grayLevel)
{

}

void createImage(unsigned char image[][WIDTH], int height)
{

}

bool writeImage(const unsigned char image[][WIDTH], int height, const string fileName)
{
    ofstream imgFile;

    imgFile.open("picture.txt");

    // <--- You may have opened the file, but how do you know that is is usable without checking?

    for (int row = 0; row < HEIGHT; row++)
    {
        for (int col = 0; col < WIDTH; col++)
            imgFile << static_cast<int>(img[row][col]) << ' ';
        imgFile << '\n';
    }

    imgFile.close();  // <--- Optional as the dtor will close the file when the function ends.
}


//=============================================================
int main()
{
    unsigned char img[HEIGHT][WIDTH];

    initialize(img);

    drawRect(img);  // <--- short 6 parameter.

    if (writeImage(img))  // <--- short 2 parameter. Also you never capture or use the return value of the function call.
        return 1;

    return 0;
}

Line 62 was changed to make use of the return value of the function call.

To better use the "" function I did this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
bool writeImage(const unsigned char image[][WIDTH], int height, const string fileName)
{
    const std::string outFileName{ "" };  // <--- Put File name here.

    std::ofstream outFile(outFileName);

    if (!outFile)
    {
        std::cout << "\n File " << std::quoted(outFileName) << " did not open" << std::endl;  // <--- Requires the "<iomanip>" header file. Or reverse the comments.
        //std::cout << "\n File \"" << inFileName << "\" did not open." << std::endl;

        return true;
    }

    for (int row = 0; row < HEIGHT; row++)
    {
        for (int col = 0; col < WIDTH; col++)
            imgFile << static_cast<int>(img[row][col]) << ' ';

        imgFile << '\n';
    }

    return false;
    //imgFile.close();  // <--- Optional as the dtor will close the file when the function ends.
}

I did not change everything here or have the chance to test it yet, but I do believe it should work.

One thing you will notice is that I use different names for some of the variables. You are not required to change the names as I have. You are free to use whatever you like.

Because the function promises to return a value line 22 is required.

Although it does not address the needs of the program sometimes it is the little things that make a difference.

Andy
Registered users can post here. Sign in or register to post.