error: use of parameter 'max' outside function body

I get an error saying: use of parameter 'max' outside function body. How do I fix this? or change it?

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
#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

void getMAX(ifstream& data, int& max);
void getData(ifstream& data, int& max, string names[], int my2DArr[][max]);

int main()
{
    ifstream data;
    int max;
    getMAX(data, max);
    string names[max];
    int my2DArr[max][max];
    getData(data, max, names, my2DArr);

    return 0;
}


void getMAX(ifstream& data, int& max)
{
    data.open("3club.txt", ios::in);
    data >> max;
    data.close();
}

void getData(ifstream& data, int max, string names[], int my2DArr[][max])
{
    data.open("3club.txt", ios::in);
    for(int i = 0; i < max; i++)
        data >> names[i];
    for(int i = 0; i < max; i++)
        for(int k = 0; k < max; k++)
            data >> my2DArr[i][k];
    data.close();
}

please and thank you

within 3club.txt:
12
Ami
Ann
Ben
Dan
Ema
Ira
Guy
Leo
Luc
Meg
Sue
Tom
0 0 0 0 0 0 0 1 0 0 1 0
0 0 0 0 0 0 0 0 1 1 0 0
0 0 0 1 0 0 0 0 1 0 0 0
0 0 1 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0
0 1 1 1 0 0 0 0 0 1 0 0
0 1 0 0 0 0 0 0 1 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
Last edited on
On some implementations of the standard library, max becomes a preprocessor keyword. This happens if one of the included headers contains:
#define max(a,b) (((a)<(b))?(a):(b))

You can avoid it by either changing the name max to something else, or by inserting the following into line 4:
1
2
3
#ifdef max
#undef max
#endif 
Oh wait! It's not that at all!

There's something wrong with this line:
void getData(ifstream& data, int& max, string names[], int my2DArr[][max])

In int my2DArr[][max], max must be a constant which can be evaluated at compile-time. In this case, it's undefined while the function header is still going on (even though you have int& max earlier in the line).

Likewise this is going to be a problem because you can't make a variable array without dynamic memory allocation.
1
2
int max;
int my2DArr[max][max];
Last edited on
oh so do I have to make it to const int max;? because i'm still getting the same problem.
is there another way to do this? What I am trying to do is read the .txt file through a function and store it within a variable so I can use it later.
You can use dynamic memory allocation or vectors.

Here's an example where I encapsulate methods and data in a single class and read with dynamic memory:
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
class LoktdFileReader
{
  std::string* names;
  int**        data;
  int          size;
  
public:
  LoktdFileReader() : names(0), data(0), size(0) {}
  ~LoktdFileReader() { CleanUp(); }
  
  void LoadFile(std::string filename)
  {
    if (size) 
      CleanUp();
    
    std::ifstream fin( filename , std::ios::in );
    fin >> size;
    
    names = new std::string[size];
    data  = new int*[size];
    
    for (int i = 0; i < size; ++i)
      std::getline( fin, names[i] );  // Supports multi-word names
      
    for (int i = 0; i < size; ++i)
    {
      data[i] = new int[size];
      for (int j = 0; j < size; ++j)
        fin >> data[i][j];
    } 
  }
  
  void Set(int val, int x, int y)
  {
    if (x < size && y < size)
      data[y][x] = val;
  }
  
  int Get(int x, int y)
  {
    if (x < size && y < size)
      return data[y][x];
    return 0; // default
  }

  int Size() { return size; }

private:
  void CleanUp()
  {
    if (names)
    {
      delete[] names;
      names = 0;
    }
    
    if (data)
    {
      for (int i = 0; i < size; ++i)
        delete[] data[i];
      delete[] data;
      data = 0;
    }
    
    size = 0;
  }
};
Last edited on
Full solution:
LoktdFileReader.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <string>
class LoktdFileReader
{
  std::string* names;
  int**        data;
  int          size;
  
public:
  LoktdFileReader() : names(0), data(0), size(0) {}
  ~LoktdFileReader() { CleanUp(); }
  
  void LoadFile(std::string filename);
  void Set     (int val, int x, int y);
  int  Get     (int x  , int y);

  int Size() { return size; }

private:
  void CleanUp();
};


main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include "LokdFileReader.h"
int main()
{
  LoktdFileReader lfr;
  lfr.LoadFile("3clob.txt");
 
  // Print/use data example 
  for (int i = 0; i < lfr.Size(); ++i)
  {
    for (int j = 0; j < lfr.Size(); ++j)
      std::cout <<  lfr.Get(i,j) << ' ';
    std::cout << std::endl;
  }  
}


LoktdFileReader.cpp (LoadFile is the important one here)
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
#include <fstream>
#include "LoktdFileReader.h"
void LoktdFileReader::LoadFile(std::string filename)
{
  CleanUp();

  std::ifstream fin( filename , std::ios::in );
  fin >> size;

  names = new std::string[size];
  data  = new int*[size];

  for (int i = 0; i < size; ++i)
    std::getline( fin, names[i] );  // Supports multi-word names
  
  for (int i = 0; i < size; ++i)
  {
    data[i] = new int[size];
    for (int j = 0; j < size; ++j)
      fin >> data[i][j];
  } 
}

void LoktdFileReader::Set(int val, int x, int y)
{
  if (x < size && y < size)
    data[y][x] = val;
}  

int LoktdFileReader::Get(int x, int y)
{
  if (x < size && y < size)
    return data[y][x];
  return 0; // default
}

void LoktdFileReader::CleanUp()
{
  if (names)
  {
    delete[] names;
    names = 0;
  }

  if (data)
  {
    for (int i = 0; i < size; ++i)
      delete[] data[i];
    delete[] data;
    data = 0;
  }

  size = 0;
}
Last edited on
Um well I haven't learned classes yet and we are suppose to use 2D arrays than vectors.
Still easy, just put it all togeather:

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
#include <fstream>
#include <iostream>
#include <string>
int main()
{
  // declare variables
  std::string* names;
  int**        data;
  int          size;

  // Load file
  std::ifstream fin( filename , std::ios::in );
  fin >> size;
    
  names = new std::string[size];
  data  = new int*[size];
    
  for (int i = 0; i < size; ++i)
    std::getline( fin, names[i] );
      
  for (int i = 0; i < size; ++i)
  {
    data[i] = new int[size];
    for (int j = 0; j < size; ++j)
      fin >> data[i][j];
  } 

  // Use data
  for (int i = 0; i < size; ++i)
  {
    for (int j = 0; j < size; ++j)
      std::cout <<  data[i][j] << ' ';
    std::cout << std::endl;
  }  

  // Clean-up
  delete[] names;
  for (int i = 0; i < size; ++i)
    delete[] data[i];
  delete[] data;
}
Last edited on
Topic archived. No new replies allowed.