swapping arguments and erros

Hello,

In the program below, I have three questions

Question 1: If I swap the arguments in inputValidate function i.e., instead of:
int inputValidate( int user_number, const string prompt) if I use
int inputValidate( const string prompt, int user_number)

and then call the function: int winning_numbers = inputValidate( "Enter 5-digit lotto numbers:", winning_numbers);

I receive errors as given below. Can you please explain these errors and perhaps point me to a source for further reading or watching to understand this issue. I tried to use const char also as char is an integral type but the errors are same.

error: invalid conversion from 'const char*' to 'int' [-fpermissive]|
error: could not convert 'winning_numbers' from 'int' to 'std::__cxx11::string {aka std::__cxx11::basic_string<char>}'|

Question 2: I received a warning for line 46 given below. Did you receive this warning and what does it mean?
Line 46 in my code is for(int i = 0; i < vector_array.size(); i++)
main.cpp|46|warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

Question 3: Program executes successfully with or without "const" in both the functions given below. Why should I prefer using const?

int inputValidate(int, string);
bool linearSearch( vector<int>, int

Thanks in advance to all the helpers.
Kind Regards
---------------------------------------------

int inputValidate(int, const string);
bool linearSearch(const vector<int>, const int);

int main()
{
vector<int> users_lotto_numbers { 13579, 26791, 26792, 33445, 55555,
62483, 77777, 79422, 85647, 93121 };

int winning_numbers = inputValidate(winning_numbers, "Enter 5-digit lotto numbers:");

bool number_found = linearSearch(users_lotto_numbers, winning_numbers);

if (number_found)
cout << "Winner!!" << endl;
else
cout << "None of you lotto numbers match the winning numbers." << endl;


return 0;
}

int inputValidate(int user_number, const string prompt)
{
cout << prompt << endl;

while (!(cin >> user_number))
{
cout << "Error. A number must be entered." << endl;
cout << prompt << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return user_number;
}

bool linearSearch(const vector<int> vector_array, const int search_term)
{
bool is_found = false;

for(int i = 0; i < vector_array.size(); i++)
{
if (search_term == vector_array[i])
is_found = true;

}

return is_found;
}
When posting code, use code tags so that the code is readable!


[code]
// formatted code goes here
[/code]


1) inputValidate() only requires 1 param of string.
2) Correct. .size() returns an unsigned value. int is signed. Instead of int use size_t
3) const stops the programmer from shooting themselves in the foot by issuing a compile time error if a value that isn't expected to change (or can't change) is changed.

Also unless a copy is required, pass vector and string by (const) ref instead of by value to avoid the unnecessary copy.

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
#include <string>
#include <vector>
#include <iostream>
#include <limits>

using namespace std;

int inputValidate(const string&);
bool linearSearch(const vector<int>&, int);

int main() {
	const vector users_lotto_numbers { 13579, 26791, 26792, 33445, 55555,
		62483, 77777, 79422, 85647, 93121 };

	if (linearSearch(users_lotto_numbers, inputValidate("Enter 5-digit lotto number: ")))
		cout << "Winner!!\n";
	else
		cout << "None of you lotto numbers match the winning number.\n";
}

int inputValidate(const string& prompt) {
	int user_number {};

	while ((cout << prompt) && !(cin >> user_number)) {
		cout << "Error. A number must be entered.\n";
		cin.clear();
		cin.ignore(numeric_limits<streamsize>::max(), '\n');
	}

	return user_number;
}

bool linearSearch(const vector<int>& vector_array, int search_term) {
	for (size_t i {}; i < vector_array.size(); ++i)
		if (search_term == vector_array[i])
			return true;

	return false;
}


Note that linearSearch can be replaced with a one-liner using std::find. 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
#include <string>
#include <vector>
#include <iostream>
#include <limits>
#include <ranges>

using namespace std;

int inputValidate(const string&);
bool linearSearch(const vector<int>&, int);

int main() {
	const vector users_lotto_numbers { 13579, 26791, 26792, 33445, 55555,
		62483, 77777, 79422, 85647, 93121 };

	if (linearSearch(users_lotto_numbers, inputValidate("Enter 5-digit lotto number: ")))
		cout << "Winner!!\n";
	else
		cout << "None of your lotto numbers match the winning number.\n";
}

int inputValidate(const string& prompt) {
	int user_number {};

	while ((cout << prompt) && !(cin >> user_number)) {
		cout << "Error. A number must be entered.\n";
		cin.clear();
		cin.ignore(numeric_limits<streamsize>::max(), '\n');
	}

	return user_number;
}

bool linearSearch(const vector<int>& vector_array, int search_term) {
	return ranges::find(vector_array, search_term) != vector_array.end();
}

Last edited on
Q1
Are you sure you didn't forget to update the declaration at the top of your code?

Q2
int is a signed type (it can represent negative numbers).
vector_array.size() returns an unsigned type (that can not represent negative numbers).

Your compiler generates a warning because comparing signed and unsigned integers is error-prone. Before doing the comparison i < vector_array.size() it will first convert the i to an unsigned integer. In this case it's not a problem because the i is never negative.

What I usually do in this situation is to use std::size_t which is an unsigned type.
 
for(std::size_t i = 0; i < vector_array.size(); i++)
It makes it a bit more clear that i is never negative and it silence the error.

Another alternative if you want to keep using signed indices is to use std::ssize(vector_array) instead of vector_array.size().

Q3
Some people prefer to use const whenever they can but personally I don't think there is much reason to use const here. I wouldn't personally do it.

It would have been important if the parameters were pointers or references because that would have affected what values the caller could pass to the function but since the arguments are "passed by value" (copied) it's essentially the same as marking a local variable as const (i.e. an implementation detail).

That said, I think it's a good idea to pass the vector and string by "const reference" in your situation to avoid making unnecessary copies.
1
2
int inputValidate(int, const string&);
bool linearSearch(const vector<int>&, int);
If you don't use const here then the caller would not be able to pass temporaries (e.g. string literals) and objects declared as const.
Last edited on
Code like:
int winning_numbers = func( winning_numbers );
makes one ask:
What is the value of winning_numbers?

The line introduces (declares) variable "winning_numbers" but in order to get its initial value (initialization) it computes something with function "func" and gives the function "winning_numbers" (that we are only about to create here) as parameter!!! That does not compute.
Topic archived. No new replies allowed.