Help me with this C++ code

I have to do this. These are the instructions.
Write a program that queries the user for an odd integer n, where n is a 3, a 5, or a 7. Create a 7x7 static matrix and use it to produce an n x n magic square as described in the problem.

The problem is the Magic Square is going above the number 7 it will take any number for some reason. I need it to be a 7x7 static matrix as described in the problem. Please help me out.

Here is my code,
/*--------------------------------------------------------------------
Program to construct magic squares of odd size.

Input: Size of square (odd #)
Output: A magic square
----------------------------------------------------------------------*/

#include <iostream> // cin, cout, >>, <<
#include <iomanip> // setw()
#include <cstdlib> // exit()
using namespace std;

const int MAX_DIM = 21;
typedef int IntTable[MAX_DIM][MAX_DIM ];

void createMagic(IntTable square, int n);
/*---------------------------------------------------------------------
Construct a magic square of odd size n.

Precondition: size of square is odd positive integer.
Postcondition: square stores an n x n magic square.
----------------------------------------------------------------------*/

void display(IntTable t, int n);
/*---------------------------------------------------------------------
Display an n x n magic square.

Precondition: None.
Postcondition: square is output to cout.
----------------------------------------------------------------------*/

int main()
{
IntTable square;
int sizeOfSquare;

cout << "\nEnter size of magic square (odd number): ";
cin >> sizeOfSquare;

createMagic(square, sizeOfSquare);
display (square, sizeOfSquare);
}


//--- Definition of createMagic()
void createMagic(IntTable square, int n)
{
if (n % 2 == 0)
{
cerr << "Size of magic square must be odd.\n";
exit(1);
}

int row,
col;

for (row = 0; row < n; row++)
for (col = 0; col < n; col++)
square[row][col] = 0;

row = 0;
col = n / 2;

for (int k = 1; k <= n * n; k++)
{
square[row][col] = k;

row--;
col++;

if (row < 0 && col >= n)
{
row += 2;
col--;
}

if (row < 0)
row = n - 1;

if (col >= n)
col = 0;

if (square[row][col] != 0)
{
row += 2;
col--;
}
}
}


//--- Definition of display()
void display(IntTable t, int n)
{
const int WIDTH = 4;

cout << "\nMagic square is:\n" << endl;
for (int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
cout << setw(WIDTH) << t[i][j];
cout << endl << endl;
}
}

typedef int IntTable[MAX_DIM][MAX_DIM ];

Sheesh! Where did you get that from?


Put your code in code tags, so that it is readable. Explain your problem more clearly: I see no attempt to test if n is 3, 5 or 7. MAXDIM=21 bears no resemblance to 7.



Your record of deleting previous posts after getting an answer does not bode well for the likelihood of getting help here. https://www.cplusplus.com/forum/general/279994/#msg1210300
Last edited on
Consider:

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <type_traits>
#include <limits>
#include <iostream>
#include <string>
#include <cctype>
#include <vector>
#include <iomanip>

template<typename T = int>
typename std::enable_if_t< std::is_integral_v<T>, T>
getInp(const std::string& prm)
{
	const auto notsp {[&]() {while (std::isspace(static_cast<unsigned char>(std::cin.peek())) && std::cin.peek() != '\n') std::cin.ignore(); return std::cin.peek() != '\n'; }};
	T n {};

	while ((std::cout << prm) && (!(std::cin >> n) || notsp())) {
		std::cout << "Invalid input. Not a(n) " << typeid(T).name() << '\n';
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	}

	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	return n;
}

template<typename T = int>
typename std::enable_if_t< std::is_integral_v<T>, T>
getInp(const std::string& prm, T low, T upper = std::numeric_limits<T>::max())
{
	T num {};

	do {
		num = getInp<T>(prm);
	} while ((num < low || num > upper) && (std::cout << "Input not in range\n"));

	return num;
}

constexpr size_t MAX_DIM {7};
using IntTable = size_t[MAX_DIM][MAX_DIM];

void createMagic(IntTable square, int n);
void display(const IntTable t, int n);

int main() {
	IntTable square {};
	int sizeOfSquare {};

	do {
		sizeOfSquare = getInp<>("Enter size of magic square (odd number 3 - 7): ");
	} while ((sizeOfSquare > 7 || sizeOfSquare % 2 == 0) && (std::cout << "Must be odd number 3 - 7\n"));

	createMagic(square, sizeOfSquare);
	display(square, sizeOfSquare);
}

void createMagic(IntTable square, int n) {
	for (int row = 0; row < n; ++row)
		for (int col = 0; col < n; ++col)
			square[row][col] = 0;

	int row {};			// Can go -ve !!
	auto col {n / 2};

	for (int k = 1; k <= n * n; ++k) {
		square[row][col] = k;

		--row;
		++col;

		if (row < 0 && col >= n) {
			row += 2;
			--col;
		}

		if (row < 0)
			row = n - 1;

		if (col >= n)
			col = 0;

		if (square[row][col] != 0) {
			row += 2;
			--col;
		}
	}
}

void display(const IntTable t, int n)
{
	static constexpr size_t WIDTH {4};

	std::cout << "\nMagic square is:\n\n";

	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < n; ++j)
			std::cout << std::setw(WIDTH) << t[i][j];

		std::cout << "\n\n";
	}
}



Enter size of magic square (odd number 3 - 7): 5

Magic square is:

  17  24   1   8  15

  23   5   7  14  16

   4   6  13  20  22

  10  12  19  21   3

  11  18  25   2   9

That looks good but doesn't work on my compiler, it says is_integral_v' is not a member of 'std'|,so don't know how to fix that.

It works on a online compiler, the only issue i have with that code is if i enter a magic square number of 1 it will work and doesn't say that its not valid.
any solution to that?
it says is_integral_v' is not a member of 'std'|,so don't know how to fix that.


Hi

The way to fix that is to look at the std symbol index on cppreference:

https://en.cppreference.com/w/cpp/symbol_index
https://en.cppreference.com/w/cpp/symbol_index#I

There is says that is_integral_v' belongs to c++17 standard, so one needs to compile with std=c++17, and it should work.

With compilers, I always try to have the latest version, and I always compile to the latest standard, even though there are only a handful of things available in c++23 at the moment, there may have been some improvement in the compiler from previous versions. The compiler vendors publish lists of the things they have fixed.

C++20 is the current standard,so you should consider upgrading your compiler.

also:

https://en.cppreference.com/w/cpp/preprocessor/replace
https://en.cppreference.com/w/cpp/feature_test

Edit:

Especially this part:

Predefined macros

The following macro names are predefined in every translation unit.
__cplusplus
denotes the version of C++ standard that is being used, expands to value 199711L(until C++11), 201103L(C++11), 201402L(C++14), 201703L(C++17), or 202002L(C++20)
Last edited on
the only issue i have with that code is if i enter a magic square number of 1 it will work and doesn't say that its not valid.


Well I had to leave something for you to do! It's easily fixed...
Topic archived. No new replies allowed.