0

For a project i'm doing, I'm required to load an input file into a 2 dimensional array for subsequent processing. The file is an "image" of 0's and 1's and looks like this:

# p01image1.txt -- Sample Image #1

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 1 1 1 1 0 0 0 0
0 0 1 1 1 1 0 0 0 0
0 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

However, when I try to put the input into the 2D Array, it ends up putting some 0's and then arbitrary numbers in the array instead like this:

0 0 0 0 984466800 32767 -885601504 32728 -885601504 32728 
984466800 32767 0 0 -885602528 32728 984466728 32767 -885398176 32728 
-885604352 32728 -885510269 32728 -890784124 32728 110527148 0 -885443879 32728 
110527148 0 157536133 0 -885510071 32728 -885443893 32728 -890789612 32728 
0 0 -885607168 32728 1 0 -967018754 23765 -885399056 32728 
-1 0 -885399056 32728 -885509698 32728 -1 0 -889561112 32728 
-964725194 23765 -885585425 32728 0 0 0 0 0 0 
0 0 0 0 0 0 -890828992 32728 -885397576 32728 
-885399296 32728 984467457 32767 984466984 32767 984466992 32767 0 0 
0 0 0 0 985621032 32767 0 32 0 0

I've never had this issue before with putting values into an array from an input file and wasn't sure if someone could give any insight to what I might be doing wrong. I'm still relatively new to c++ so I apologize in advance.

My function for opening the input file is:

// ****************************************
// Program Title: Project 1
// Project File: Project01.cpp
// Name: Noah Sickels
// Course Section: CPE-212-02
// Due Date: 2/14/22
// Program Description: Image Manipulation Program
// ****************************************
#include <bits/stdc++.h>

void LoadImage(const string imagefile, int image[MAXROWS][MAXCOLS])
// LoadImage() must open the image file for input and load the image into a
// two-dimensional array for subsequent processing.  If the file does not open,  
// then print error message and exit the program by invoking the function exit(1)
//
// First parameter is a string that will hold the name of the input file
// Second parameter is a two-dimensional array of integers representing the image
//
// Note: Correct operation of this function is critical!!  If one cannot
//       correctly load images into the array from the file, then one 
//       cannot test the image processing operations.
//
{
    ifstream inFile;
    inFile.open(imagefile);
    
    for(int i = 0; i < MAXROWS; i++) {
        for(int j = 0; j < MAXCOLS; j++) {
            if(! (inFile >> image[i][j])){
                cout << "Error reading from file, terminating program..." << endl;
                exit(1);
            }
        }
    }
    inFile.close();

    for (int i = 0; i < MAXROWS; i++) {
        for (int j = 0; j < MAXCOLS; j++) {
            cout << image[i][j] << " "; //space between columns
            }
        cout << endl; //newlines for rows
    }
}  // End LoadImage()
/***********************************************************************/
void FlipHorizontal(int image[MAXROWS][MAXCOLS])
// FlipHorizontal() - must flip the image horizontally.  For example,
// column zero exchanged with column N-1, column one exchanged with column N-2, etc.
//
// First parameter is a two-dimensional array of integers representing the image
//
{
    int temp;
    for(int i = 0; i < MAXROWS; i++){
        for(int j = 0; j < MAXCOLS / 2; j++){
           temp = image[i][j];
           image[i][j] = image[i][MAXCOLS - j - 1];
           image[i][MAXCOLS - j - 1] = temp;
        }
    }
}  // End FlipHorizontal()
/***********************************************************************/
void FlipVertical(int image[MAXROWS][MAXCOLS])
// FlipVertical() - must flip the image Vertically.  For example,
// row zero exchanged with row N-1, row one exchanged with row N-2, etc.
//
// First parameter is a two-dimensional array of integers representing the image
//
{
    int temp;
    for(int i = 0; i < MAXROWS / 2; i++){
        for(int j = 0; j < MAXCOLS; j++){
            temp = image[i][j];
            image[i][j] = image[MAXROWS - 1 - i][j];
            image[MAXROWS - i - 1][j] = temp;
        }
    }
}  // End FlipVertical()
/***********************************************************************/
void Transpose(int image[MAXROWS][MAXCOLS])
// Transpose() - must flip the image across the primary diagonal row = column as
// with a matrix transpose
//
// First parameter is a two-dimensional array of integers representing the image
//
{
    int temp[MAXROWS][MAXCOLS];
    for(int i = 0; i < MAXROWS; i++) {
        for(int j = 0; j < MAXCOLS; j++) {
            temp[j][i] = image[i][j];
        }
    }
}  // End Transpose()
/***********************************************************************/
void RotateCW(int image[MAXROWS][MAXCOLS])
// RotateCW() - must rotate the image 90 degrees clockwise.  
//
// First parameter is a two-dimensional array of integers representing the image
//
{
    int temp[MAXROWS][MAXCOLS];
    
    for(int i = 0; i < MAXROWS; i++){
        for(int j = 0; j < MAXCOLS; j++){
            temp[i][j] = image[MAXROWS - j - 1][i];
        }
    }

    for(int i = 0; i < MAXROWS; i++){
        for(int j = 0; j < MAXCOLS; j++){
            image[i][j] = temp[i][j];
        }
    }
}  // End RotateCW()
/***********************************************************************/
void RotateCCW(int image[MAXROWS][MAXCOLS])
// RotateCCW() - must rotate the image 90 degrees counter clockwise.  
//
// First parameter is a two-dimensional array of integers representing the image
//
{
    int temp[MAXROWS][MAXCOLS];

    for(int i = 0; i < MAXROWS; i++){
        for(int j = 0; j < MAXCOLS; j++){
            temp[i][j] = image[MAXROWS - j - 1][MAXROWS - i - 1];
        }
    }

    for(int i = 0; i < MAXROWS; i++){
        for(int j = 0; j < MAXCOLS; j++){
            image[i][j] = temp[i][j];
        }
    }
}  // End RotateCCW()
/***********************************************************************/

The main.cpp file that we are required to use is here:

//
// main.cpp --  Project01, CPE212 Fall 2010 -- C++ Review Project
//
// Driver program for Image Processing Program which is used to test each
// image processing operation.
//
// DO NOT SUBMIT OR SUBMIT THIS FILE
//

// List of allowed include files appear below
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>

using namespace std;                    // Global using declaration

// Global Constants -- you may use these global constants in your code
const int MAXROWS = 10;                 // Maximum number of rows in image
const int MAXCOLS = 10;                 // Maximum number of columns in image

// Function Prototypes for functions included at the end of main.cpp
void Print(const int image[MAXROWS][MAXCOLS]);
void Bars();

// Function Prototypes for the functions you must implement in project01.cpp
void LoadImage(const string imagefile, int image[MAXROWS][MAXCOLS]);
void FlipHorizontal(int image[MAXROWS][MAXCOLS]);
void FlipVertical(int image[MAXROWS][MAXCOLS]);
void RotateCW(int image[MAXROWS][MAXCOLS]);
void RotateCCW(int image[MAXROWS][MAXCOLS]);
void Transpose(int image[MAXROWS][MAXCOLS]);


// Start of main() function

int main (int argc, char * const argv[])      // Command-line arguments (more on this later)
{
  ifstream inputs;                // Input file stream variable for test file
  char op, ch;                    // Hold operation and optional char input from test file
  string  comment;                            // Holds comment string input from test file
  int image[MAXROWS][MAXCOLS];                // Array of integers representing image
  string imagefile;                           // Name of image file

  
  // Output usage message if test input file name is not provided
  if (argc != 2)
  {
    cout << "Usage:\n  project01  <inputfile>\n";
    return 1;
  }
  
  // Attempt to open test input file -- terminate if file does not open
  inputs.open(argv[1]);
  if (!inputs)
  {
    cout << "Error - unable to open input file" << endl;
    return 1;
  }

  // Process comment line from input file
  getline(inputs, comment);                    // Input file header comment
  cout << endl << comment << endl << endl;     // Output file header comment
    
    
  // Below is primary loop that processes each operation appearing within the test file.
  // Starts with an initial priming read of first operation
    
  inputs >> op;         // Attempt to input first test operation from file
    
  while (inputs)                // While Not-EOF
  {
    switch (op)                 // Process operation input from test file
    {
      case '#':   // Test file comment
                      getline(inputs, comment);      // Input and echo the comment appearing in the test file
                      cout << '#' << comment << endl;
                      break;
            
      case 'p':   // Print Grid 
                      Print(image);                  // Function definition appears at the end of this file
                      break;                    
            
      case 'b':   // Print Bars
                      Bars();                        // Function definition appears at the end of this file
                      break;                
            
      case 'i':   // Load Image
                      inputs >> imagefile;           // Input name of imagefile from test file
                      LoadImage(imagefile, image);   // Implement this function in project01.cpp
                      break;
                      
          case '+':   // Rotate Image Clockwise 90 Degrees
                      RotateCW(image);               // Implement this function in project01.cpp
                      break;

          case '-':   // Rotate Image Counterclockwise 90 Degrees
                      RotateCCW(image);              // Implement this function in project01.cpp
                      break;              

      case 'v':   // Flip Image Vertical
                      FlipVertical(image);           // Implement this function in project01.cpp
                      break;
                        
      case 'h':   // Flip Image Horizontal
                      FlipHorizontal(image);         // Implement this function in project01.cpp
                      break;

      case 't':   // Transpose Image Across Major Diagonal
                      Transpose(image);              // Implement this function in project01.cpp
                      break;            

      default:    // Error
                      cout << "Error - unrecognized operation '" << op << "'" << endl;
                      cout << "Terminating now..." << endl;
                      return 1;
                      break;
    }
    cout << endl;
      
    inputs >> op;                                // Attempt to input next command
  }
 
  
  return 0;
}

/************** Implementation of Print() and Bars() functions ********************/

// DO NOT MODIFY THIS CODE

void Print(const int image[MAXROWS][MAXCOLS]) 
// Print() -- outputs image row-by-row in desired format substituting
// * for 1 and - for 0.
{
    for(int r=0; r < MAXROWS; r++)               // Loop to visit each row in image
    {
        for(int c=0; c < MAXCOLS; c++)       // Loop to output every element on current row
        {
            if (image[r][c] == 1)        // Output appropriate symbol
            {
                cout << '*';
            }
            else if (image[r][c] == 0)
            {
                cout << '-';
            }
            else
            {
                cout << 'X';
            }
        }
        cout << endl;
    }
    
}  // End Print()

void Bars()
// Bars() -- prints two horizontal rows of bars 
{
    cout << "#################################################################" << endl;
    cout << "#################################################################" << endl;
}  // End Bars()

/************** DO NOT DELETE *************/
// The preprocessor directive below will import the function definitions 
// from the file project01.cpp and place them at the end of this file creating an
// Expanded Source File which is forwarded to the compiler for compilation.

#include "project01.cpp"

/**************  End of main.cpp  ***************/


GeneralIT
  • 31
  • 3
  • There must be more to it, [This works...](https://godbolt.org/z/M5q3rMTh5). And BTW, you should avoid `using namespace std;`. I only left it out of laziness. – lakeweb Feb 09 '22 at 22:14
  • @lakeweb I just added the full main.cpp file as well – GeneralIT Feb 09 '22 at 22:21
  • Test for successful read here: `inFile >> image[i][j];`. If you don't you won't know if the read failed. Once a read fails, a failure flag is set and all subsequent reads will automatically fail. If you don't care about any individual read, a quick `if (inFile)` before closing the file will let you know if anything went wrong anywhere while reading the file. – user4581301 Feb 09 '22 at 22:22
  • @user4581301 I just changed that in the program. I apprecaite the advice! – GeneralIT Feb 09 '22 at 22:30
  • @lakeweb Is there a specific reason to avoid using namespace std? – GeneralIT Feb 09 '22 at 22:34
  • @user4581301 Not sure if I incorrectly did it, program temrinates each time now. – GeneralIT Feb 09 '22 at 22:37
  • [Why is "using namespace std;" considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – user4581301 Feb 09 '22 at 22:41
  • 1
    If there is something wrong in the file reading it'll terminate every time AND explain why previously you had garbage in the array (file wasn't being read correctly). Print out `i` and `j` to see where it died ( or step through the program with a debugger) and see what's at that spot in the file. You may need a hex editor to see the actual file contents in case there are invisible characters in the file. – user4581301 Feb 09 '22 at 22:43
  • Here is the [long winded discussion](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) on it. Protecting stuff in namespaces keeps that stuff where it belongs. And as user4581301 points out, use your debugger! It is the most valuable tool you have. – lakeweb Feb 09 '22 at 22:47
  • @user4581301 I had the program print out i and j and they were both at 0. Not sure what would be wrong with the input files, we were told to assume the input files would be valid. Would it be possible that it's the way I'm opening the file? Or would it have anything to do with the first line that is a comment and the second line that is blank? – GeneralIT Feb 09 '22 at 22:54
  • if `# p01image1.txt -- Sample Image #1` is inside the file, oh yeah. That'll kill the reader instantly. Anything that can't be converted into an `int` by `inFile >> image[i][j]` will set the fail flag and stop reading. I figured that was a bit of information for us readers that accidentally got included in the formatted block or I would have brought it up earlier. Use `inFile.ignore(numeric_limits::max(), '\n')` to eat the first line and throw it away. If the second line is all whitespace `>>` will discard it all for you. – user4581301 Feb 09 '22 at 23:00
  • You'll need to `#include ` to get `numeric_limits`. – user4581301 Feb 09 '22 at 23:01

1 Answers1

2

I figured out the problem, it was my own dumb mistake. The issue was the text line at the beginning that was causing the array to give those values. Since we are not allowed to use the limits function, so I used getline() to ignore the first line in the file and the array copied correctly.

GeneralIT
  • 31
  • 3
  • 1
    Recommend an edit to clarify which function is *the function* in *Since we are not allowed to use the function*. Other than that, `getline` is a good solution. – user4581301 Feb 09 '22 at 23:46