How to make arrays work when "Expression must have a constant value." keeps showing up

closed account (3UCMGNh0)
"Expression must have a constant value." appears four times in the error list and are the only errors. They appear for lines 39 and 51. I've gone to stock overflow and they've given me minor almost unnoticeable tips. Can someone just fix this code for me. What I mean is make this code functional while also keeping it accurate.

I've tried allocating the memory and I changed "mystr.length();" to a number and while that allowed the program to run, it provided invalid results. Plz someone.

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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
  // ConsoleApplication2.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include "pch.h"
#include <iostream>
#include <string>
#include <fstream>
#include <istream>


using namespace std;

int main()

{

	char letter = 'Y';

	int position = 0;

	string productNames[7] =

	{ "Pen", "Paper", "Computer", "Pepsi", "Coke", "Book", "Scanner" };

	int prizeOfproducts[7] = { 10, 2, 5000, 50, 45, 400, 2000 };

	while (letter == 'Y')

	{

		string mystr = "";

		cout << "enter the product name you want to search : ";

		cin >> mystr;

		int n = mystr.length();

		char char_array[n + 1];

		strcpy(char_array, mystr.c_str());

		bool flag = false;

		for (int i = 0; i < 7; i++)

		{

			int m = productNames[i].length();

			char char_arrayOrig[m + 1];

			strcpy(char_arrayOrig, productNames[i].c_str());

			if (strstr(char_arrayOrig, char_array) == NULL)

			{

				flag = false;

			}

			else

			{



				flag = true;

				position = i;

				break;

			}

		}

		if (!flag)

		{

			cout <<

				"entered product not found in the product list . Do you want to search again Y/N ? : ";

			cin >> letter;

		}

		else

		{

			cout << "The product is found and this is the desciption : \n";

			cout << "The product Name is : ";



			cout << productNames[position];

			cout << "\n";

			cout << "The product prize is : ";

			cout << prizeOfproducts[position];



			cout << "\n";

			int number_of_items;

			cout << "how many items you want to order : ";

			cin >> number_of_items;



			cout << "Total prize is :";

			cout << prizeOfproducts[position] * number_of_items;

			break;

		}



	}

	return 0;

}
Last edited on
Include <vector> and change
 
string productNames[7] = ...
to
 
std::vector<string> productNames = ...
and change
 
int prizeOfproducts[7] = ...
to
 
std::vector<int> prizeOfproducts = ...
Please post the entire errors. Variable length array (line 39/51) are not a good idea. Some compiler may consider it an error.

For the c part you need to

#include <string.h>


However, it is not a good idea to mix c style strings (strcpy(...)/strstr(...)) with c++ string. The c++ string provides the same functionality like the c counter part and more. See:

http://www.cplusplus.com/reference/string/string/?kw=string

For strstr(...) you can use find(...):
http://www.cplusplus.com/reference/string/string/find/

productNames[i].find(mystr) != std::string::npos
closed account (3UCMGNh0)
@coder777 Okay, did I edited the comments and posted all the errors in my first comment, though you already predicted them. Lines 39/51 are the only things preventing me from being done with this. Please help.

@Peter87 made all the changes you asked for.
Last edited on
1
2
3
4
string mystr = "";
cin >> mystr;
int n = mystr.length();
char char_array[n + 1]; // error: C++ does not support VLA 

The char_array is a plain array with automatic storage duration.
In other words, some stack memory is reserved for it when function is called/scope is entered.
The instruction to reserve memory must have the number of bytes. The instruction is created during compilation.
Compiler cannot know what all the users will write on all the runs of the program.

C language does support VLA, a way to have array of dynamic size. C++ does not.


There are multiple possibilities:

* Static size and handle "too much input" somehow:
1
2
char char_array[1000] {};
if ( 999 < mystr.length() ) return 1;


* Dynamically allocated array:
vector<char> char_array( n + 1, 0 );

* Stick with std::strings all the way:
string char_array = mystr;
Are you seriously copying the content of std::strings into char* to compare them?
To compare two std::strings… just compare them!
1
2
3
4
5
6
7
8
9
10
#include <iostream>

int main()
{
    std::string one = "whatever";
    std::string two = "whatever";
    if( one == two ) {
        std::cout << "They are the same!\n";
    }
}


In case you want to get rid of spaces inside them, you can compare them char by char inside a loop:
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
#include <iostream>

int main()
{
    std::string first  = " whatever ";
    std::string second = "what ever";

    // Really awkward: it would be far better to remove every space before!
    int len_a = static_cast<int>( first.length() );
    int len_b = static_cast<int>( second.length() );

    bool equal { true };
    for ( int index_a = 0, index_b = 0;
          index_a < len_a && index_b < len_b;
          ++index_a, ++index_b )
    {
        while ( first.at(index_a) == ' ' && index_a < len_a - 1 ) {
            ++index_a;
        }
        while ( second.at(index_b) == ' ' && index_b < len_b - 1 ) {
            ++index_b;
        }
        std::cout << "Comparing first.at(" << index_a << ") ('"
                  << first.at(index_a) << "') with second.at("
                  << index_b << ") ('" << second.at(index_b) << "')... ";

        if( first.at(index_a) != second.at(index_b) ) {
            std::cout << "difference found!\n";
            equal = false;
            break;
        }
        std::cout << "ok!\n";
    }
    std::cout << "Product " << (equal ? "found" : "not found") << '\n';
}

Output:
Comparing first.at(1) ('w') with second.at(0) ('w')... ok!
Comparing first.at(2) ('h') with second.at(1) ('h')... ok!
Comparing first.at(3) ('a') with second.at(2) ('a')... ok!
Comparing first.at(4) ('t') with second.at(3) ('t')... ok!
Comparing first.at(5) ('e') with second.at(5) ('e')... ok!
Comparing first.at(6) ('v') with second.at(6) ('v')... ok!
Comparing first.at(7) ('e') with second.at(7) ('e')... ok!
Comparing first.at(8) ('r') with second.at(8) ('r')... ok!
Product found

Anyway, your code uses std::cin, so there can’t be spaces.

- - -
"Expression must have a constant value." appears four times. I've gone to stock overflow and they've given me minor almost unnoticeable tips.

That forum is based on the idea of “the best answer”: you cannot ask the same question hundreds of times like here; and you asked something you were supposed to know, if you use C-style char arrays.
The size of a C-style char array must be known at compile time.
It means you can declare a C-style char array only by a constant value:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <cstring>
#include <iostream>

int main()
{
    const char myarr_1[9] = "whatever"; // '9' is constant
    const char myarr_2[] = "whatever";  // the compiler will count the characters
    const int mylength = 9;
    const char myarr_3[mylength] = "whatever"; // mylength is const

    // Otherwise you need to allocate memory in the heap and get a pointer to
    // that memory. These kind of pointers are often called dynamic arrays:
    std::string s = "whatever";
    char* myarr_4 = new char[ s.length() + 1 ];
    std::strcpy(myarr_4, s.c_str());

    std::cout << myarr_1 << ' '
              << myarr_2 << ' '
              << myarr_3 << ' '
              << myarr_4 << '\n';
}

Output:
whatever whatever whatever whatever

@Peter87
I don't think that the arrays need to be changed to vectors since the arrays themself remaine like they are.

The last line of my previous post is basically the solution:
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <iostream>
#include <string>
#include <fstream>
#include <istream>


using namespace std;

int main()

{

	char letter = 'Y';

	int position = 0;

	string productNames[7] =

	{ "Pen", "Paper", "Computer", "Pepsi", "Coke", "Book", "Scanner" };

	int prizeOfproducts[7] = { 10, 2, 5000, 50, 45, 400, 2000 };

	while (letter == 'Y')

	{

		string mystr = "";

		cout << "enter the product name you want to search : ";

		cin >> mystr;

		int n = mystr.length();

		char char_array[n + 1];

		strcpy(char_array, mystr.c_str());

		bool flag = false;

		for (int i = 0; i < 7; i++)

		{

			int m = productNames[i].length();

			char char_arrayOrig[m + 1];

			strcpy(char_arrayOrig, productNames[i].c_str());

			if (strstr(char_arrayOrig, char_array) == NULL)
			if (productNames[i].find(mystr) == std::string::npos) // Note
			{

				flag = false;

			}

			else

			{



				flag = true;

				position = i;

				break;

			}

		}

		if (!flag)

		{

			cout <<

				"entered product not found in the product list . Do you want to search again Y/N ? : ";

			cin >> letter;

		}

		else

		{

			cout << "The product is found and this is the desciption : \n";

			cout << "The product Name is : ";



			cout << productNames[position];

			cout << "\n";

			cout << "The product prize is : ";

			cout << prizeOfproducts[position];



			cout << "\n";

			int number_of_items;

			cout << "how many items you want to order : ";

			cin >> number_of_items;



			cout << "Total prize is :";

			cout << prizeOfproducts[position] * number_of_items;

			break;

		}



	}

	return 0;

}
closed account (3UCMGNh0)
@keskiverto YOU ARE A LIFESAVER BRO!!!
I don't think that the arrays need to be changed to vectors since the arrays themself remaine like they are.

You're right. I was focusing on the wrong arrays.
Topic archived. No new replies allowed.