0

I'm working on a program that is supposed to load a 2D array from a file.

My file looks like this, with the first number indicating the size of the array:

10
7 6 9 4 5 4 3 2 1 0
6 5 5 5 6 5 4 3 2 1
6 5 6 6 7 6 8 4 3 2
1 5 6 7 7 7 6 5 4 3
5 5 6 7 6 7 7 6 5 9
5 6 7 6 5 6 6 5 4 3
5 6 7 9 5 5 6 5 4 3
5 5 6 7 6 6 7 6 5 4
5 9 5 6 7 6 5 0 3 2
5 5 5 5 6 5 4 3 2 7

And here is my code so far:

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

int main() {
ifstream prog;
prog.open("../prog1.dat");

    //If file can't be opened, exit
    if (!prog) {
        cerr << "File could not be opened" << endl;
        exit(EXIT_FAILURE);
    }
    else {
        while (!prog.eof()) {
            int size = 100, i, j;
            prog >> size; 
            int **numArray = new int* [size];
                for(i = 0; i < size; i++) {
                    numArray[i] = new int[size];
                    for(j = 0; j < size; j++) {
                        cout <<numArray[i][j] << " ";
                    }
                    cout << endl;
                }

        prog.close(); 
        return 0; 
        }
    }

}

But one of the errors I'm getting says that "expression must have a constant value" on the

int numArray[size][size];

portion of my code.

My problem is that I don't know how to go about making this a constant since I'm getting the size from the file as if I don't already know the size of the array.

This is my first C++ program and I'm pretty much teaching it to myself as I go since my professor seems to think that because we should know how to do these things in Java that we don't have to go over it in class. The examples I've found dealing with using constants say it should be something like this:

const int size = *value*;

but since my program is supposed to look in the file for the size, I'm not sure how to do this. Any suggestions? Also, like I said, I'm really new at this so if you happen to spot anything else in my code that needs to be fixed, that'd be greatly appreciated as well.

  • 1
    C99 supports that, C++ does not. Use `std::vector`. – Jonathan Potter Sep 11 '14 at 05:52
  • Are you required to use an `int [r][c]` in your code? C++ has `std::vector` that would make this easier. – DCoder Sep 11 '14 at 05:52
  • Yes, part of the directions say to use a 2D array, I'm about ready to just say screw it and do it with a vector though just so I can get done and go to bed ha. –  Sep 11 '14 at 05:58
  • 1
    If you don't use std::vector there is sort of **[duplicate here](http://stackoverflow.com/a/936709/2285592)**. As stated by others it's not allowed declare a double array like this int numArray[size][size], because the size is unknown at compile time. You will have to allocate and delete the array(s). – Stígandr Sep 11 '14 at 06:01
  • @Beth `std::vector` is the C++ equivalent of a Java array. If you are happy to use the term "array" to describe a Java array, then you must also apply it to a C++ vector – M.M Sep 11 '14 at 06:43
  • Ah ok, I was under the impression that they were different since I'd seen articles and tutorials on when to use a vector rather than an array, how the two are different, etc –  Sep 11 '14 at 06:51

6 Answers6

3

When you define an array in C++ the size must be known at compile time. That's why the compiler produces an error for the line:

int numArray[size][size];

You can use std::vector to create dynamic arrays.

std::vector<std::vector<int>> numArray(size, std::vecot<int>(size));

Now, numArray can be used just like a statically defined array.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
1

It is impossible. As you don't know size of array at compile time, you should allocate memory dynamically.

Use std::vector:

std::vector<std::vector<int> > numbers;
Ivan Aksamentov - Drop
  • 12,860
  • 3
  • 34
  • 61
  • I know vector would be by far the best way to go, but part of the directions are to use a 2D array, so figure I better stick to trying to do it that way, my professor's extremely picky. Even if we get the same exact result, if we didn't do it the way he wanted us to we don't get any credit. –  Sep 11 '14 at 05:56
  • also note that std::map may be something to look into if you want 2D – Alex_Nabu Sep 11 '14 at 06:00
  • @BethTanner Please also note, that multidimensional arrays (so as vectors) could be considerably slower than one-dimensional arrays. But, luckily, you could very easily wrap plain array so it looks like n-dimensional array. It is not just a matter of interface (you can emulate interface of 2D array by means of operator overloading), but also of performance. For more info, see my recent answer [here](http://stackoverflow.com/questions/25611622/how-to-access-to-the-index-of-a-2d-vector-by-at-function/25611857#25611857) – Ivan Aksamentov - Drop Sep 11 '14 at 10:36
0

The answers referring to vectors are correct and the preferred method for creating dynamic arrays in C++, however; your code can work. The problem you have is that you are trying to define a dynamic array on the stack and you can't do that. You need to create the array on the heap.

Here is a good example on how to do that: How do I declare a 2d array in C++ using new?

Community
  • 1
  • 1
Leon
  • 12,013
  • 5
  • 36
  • 59
0

You could also do this by declaring numArray as a pointer to int pointer, then allocate numArray and its contents on loading the size.

Be careful of freeing the memory correctly after use, tho.

GKelly
  • 3,835
  • 4
  • 38
  • 45
0

This should work. See, you just use the for loop.

for(i = 0; i < size; i++) {
    for(j = 0; j < size; j++) {
        cout <<numArray[i][j] << " ";
    }
    cout << endl;
 }
jax
  • 728
  • 1
  • 11
  • 31
  • Ok, this is at least displaying something, however, it's not printing out the array, it's just a bunch of random numbers. It's printing -042150451 over and over, so I'm thinking it's not loading the array properly (obviously ha) –  Sep 11 '14 at 09:04
  • I don't know specifically, it just doesn't seem to be loading the array correctly since the numbers it's displaying aren't the same numbers that are in the file. –  Sep 11 '14 at 09:25
  • I see, you mixed the for loop for reading the array with the for loop for writing the array. They should be seperate. – jax Sep 11 '14 at 09:37
-1

Constants can mean either a variable which doesn't change or a literal, which is any value not a variable, such as 1, 4, 5. These are integer literals. In this context, the compiler is saying that the value for the delcaraing the size of the array takes a literal. Replace 'Size' with an integer.

Better yet, use

#define SIZE 100

Macro in C/C++ are just values that are expanded during compilation.

Or if you want to change the array during runtime, you can use pointers.

int *array[10000]; // make the array large enough for most cases
// note the '*' that is a what makes a pointer

// read the size from file


for (int i = 0, i < size; ++i) 
{
    array[i] = new int [size];      // use 'new' to dynamically create an array
}

Pointers allows creating arrays with variables and literals.

Here a version of your program using pointers. Study it to learn how it works.

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

int main() {
ifstream prog;
prog.open("prog1.dat");

    //If file can't be opened, exit
    if (!prog) {
        cerr << "File could not be opened" << endl;
        exit(EXIT_FAILURE);
    }

    int size = 100, i, j;
    //prog >> size; 
    int **numArray = new int*;   // pointers used here

        for(i = 0; i < size; i++) {
            numArray[i] = new int[size];     // pointer used here
            for(j = 0; j < size; j++) {
                prog >> numArray[i][j];
            }
        }
        return 0; 
        cout << numArray[i][j];
}    
jax
  • 728
  • 1
  • 11
  • 31
  • This corrected the problem I was having, however now I'm getting a few other errors at the portion of the code where I'm trying to display the array. The errors are "undeclared identifier i and j" and "identifier undefined i and j". Am I just trying to display the array in the wrong place? –  Sep 11 '14 at 06:05
  • Your variables i and j are out of scope. The declarations should be outside of the scope of the for loop. Right now, you can only use them inside your for loop. Just declare them outside the for loop. – jax Sep 11 '14 at 06:10
  • That's what I figured, I've never been good with scope in any programming language ha. declaring them outside the loop fixed those errors, however, now I don't think the array is being loaded correctly. I'm using Visual Studios 2012 and when I run the file a black box pops up for a few seconds and then goes away. But I'm not getting any errors like the program has crashed or anything. –  Sep 11 '14 at 06:17
  • I think it's because you're not creating the array correctly. – jax Sep 11 '14 at 06:21
  • This is a definite possibility ha –  Sep 11 '14 at 06:33
  • 1
    `#define SIZE 100` is considered bad style in C++. Macro names do not follow ordinary lookup rules (e.g. respect namespaces) . Instead, `const size_t SIZE = 100;` is preferred. Or `int` if that's what you want. – M.M Sep 11 '14 at 06:42
  • I think you meant `int **numArray = new int* [size];`. Also, having `cout << ` after ` return 0;` is not very productive – M.M Sep 11 '14 at 06:45
  • I've modified my code to reflect your suggestions, along with @MattMcNabb's suggestions, but am getting the same result. There is something written in the black box that pops up, but it goes away too quickly for me to read what it says. –  Sep 11 '14 at 06:49
  • You're probably running the program in non-debug mode. If ran in debug it will pause and give you a choice to exit. The shortcut to run in debug is F5. – jax Sep 11 '14 at 06:55
  • You're right, I ran it in debug mode and what is written in the black box is my File could not be opened message... –  Sep 11 '14 at 07:00
  • That particular problem was caused by a path error so I was able to fix that, however now the program crashes and I am given an error at the cout << numArray[i][j] portion of the code that says "First-chance exception at 0x0085912E in Program1.exe: 0xC0000005: Access violation reading location 0xFDFDFF8D." –  Sep 11 '14 at 07:03
  • It looks like a segmentation fault. What does your code look like right now. You can editor your post and update the code. – jax Sep 11 '14 at 07:21
  • Have you uncommented out size? – jax Sep 11 '14 at 07:25
  • Not sure what's going on, when I check the value of i and j at that point of the code that's throwing the error, here is what it's showing for the value of i "0xfdfdfdfd" but j is showing a correct value of 10. –  Sep 11 '14 at 07:43
  • It's the last cout statement. Your i is no longer less than 'size'. When that executes your array goes out of bounds, and hence the error. Remove that and that should work. – jax Sep 11 '14 at 07:57
  • Ok, I see what you mean, but that's gonna cause problems too. See, the number 10 on it's own line in the file isn't supposed to be included in the array, it's simply supposed to be used to show the program the size of the array, so if it's being counted as a row in the array that's gonna throw things off and the output won't be correct. At least that's what I'm thinking. –  Sep 11 '14 at 08:01
  • I'm assuming by last line you mean the last line of the file right? –  Sep 11 '14 at 08:01
  • I'm not sure what you're saying. But I don't see how that would cause problems. – jax Sep 11 '14 at 08:03
  • Well if you're saying remove the last line of the file I can't do that, this is the file my professor posted for us to use and the one that he will be using to grade the program, so by removing the last line, that's going to cause my output to be different than his. If the code is counting that first 10 as the first index in the array, that's not how it should be, it should technically be starting at the first number of the second row. –  Sep 11 '14 at 08:07
  • I have no idea how it works in C++, but in the little bit of Java I've learned, in this situation (reading a file and storing the results into a file), you'd do something like int size = fin.nextInt(); and that would store the first number in the file as the size, then you'd use s loop to go through the file and load the array. –  Sep 11 '14 at 08:08
  • Maybe this has something to do with it? When I'm going through on the debugger, at the portion of the code where I'm creating the array with the pointer (int **numArray = new int* [size];) the value on int **numArray is shown as "0x0133a1a8" –  Sep 11 '14 at 08:14
  • No, it's the cout at the end. To load the array in C++, it usually done the same way as you read it. Which is by using the for loop. – jax Sep 11 '14 at 08:28
  • So how can I fix the error with the cout without deleting lines from my file? –  Sep 11 '14 at 08:32
  • you can't. the problem is that statment as I explained earlier. – jax Sep 11 '14 at 08:53
  • So how would I go about displaying the contents of the array? Sorry, like I said, I'm extremely new to this so have never encountered any of this before. –  Sep 11 '14 at 08:55
  • 1
    for(i = 0; i < size; i++) { for(j = 0; j < size; j++) { cout < – jax Sep 11 '14 at 08:58