No Matching Function for call?

Hi,
I'm writing a number analysis program for a course. The program reads integers from a text file, then stores them in an array. A requirement of the assignment is that a "Function Reads the numbers from the file, stores them into the array. The function accepts three arguments: reference to the input file (ifstream), array of numbers, array size. "
I'm not sure why I'm getting this error and would appreciate it if someone could point it out? Thanks!

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 <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;

void readFile(ifstream &, int [], int); //Function prototypes.



int main()
{
    const int ARRAY_SIZE=12;
    int numbers[ARRAY_SIZE];
    string fileName;
    cout << "Please enter the name of the file to read numbers for Number Analysis Program:";
    cin >> fileName;
    readFile(fileName, numbers, ARRAY_SIZE); //The "no matching function for call to 'readFile'" error appears here
    
    return 0;
}

void readFile(ifstream &inputFile, int nums[], int size)
{
    int count=0;
    inputFile.open("numbers.txt");
    while (count < size && inputFile>>nums[count])
        count++;
    if (!inputFile)
        cout << "Error opening the file." << endl;
}



Hello ayleeta,

Welcome to the forum.

On line 19 the first parameter is the name of the file when it should be the file stream as the prototype shows.

I see you did open the file stream in the function, so there is no need to pass the ifstream or a file name because you do all of that in the function.

Hope that helps,

Andy

Hi Andy,
I still do not fully understand what line 19 (where I'm calling the function) should look like. What should x be if the function call is as below?

 
readFile(x, numbers, ARRAY_SIZE); 


Should it be
 
readFile(ifstream &, numbers, ARRAY_SIZE);

or
 
readFile(&inputFile, numbers, ARRAY_SIZE);
Hello ayleeta,

First you have to understand the difference between the "fileName" and file stream. The "fileName" is defined as a "std::string" and what you have not defined yet is the file stream.

Based on what you have the prototype and function definition and function call have to match. Only the function prototype and definition match with their parameter list the function call does not. What you need to do first in main is define the file stream: std::ifstream inputFile;. Then in the function call the first parameter would be "inputFile".

This would make everything match and work properly. Then in the function you can open the file and have a working file stream.

In the "readFile" function you have the if statement and while loop backwards. You ar checking to see if the file is open after you have tried to read the file. If the file did not open you would end up reading nothing. This might work, but the more appropriate way is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void readFile(ifstream &inputFile, int nums[], int size)
{
	int count = 0;
	inputFile.open("numbers.txt");

	if (!inputFile)
	{
		cout << "Error opening the file." << endl;
		std::this_thread::sleep_for(std::chrono::seconds(5));  // Requires header files "chrono" and "thread"
		exit(1);
	}

	while (count < size && inputFile >> nums[count])
		count++;
}


In the third example you are sending the address of "inputFile". Not what you want. In the second example I am not sure if the '&' has any meaning in a function call, but it is not needed just the variable name is used in function calls. Unless you need to send an address then "&variableName" would work.

Hope that helps,

Andy
Hello ayleeta,

When I ran the program it does not work well. On lines 17 and 18 you input a file name that is never used because in the function you use a different file name ot open the file stream.

For any further testing I will have to make up an input file. What you use would be better so that we are using the same data to work with.

I altered the prototype, function definition and function call to include the file name as defined in main. The function definition now looks like this:
void readFile(std::ifstream &inputFile, const std::string fileName, int nums[], const int size) and in the function the open statement is now:inputFile.open(fileName);.

What you have works, but what I would have done is define the file stream, ask for the file name and open the file stream all in the function. Only passing the array and size and I would pass the array by reference although it is not necessary.

As a side note: be careful when asking the user to input a file name. The user may not always spell or type correctly when entering a file name. Then there is the question to expect the user to put the extension on the name or allow the program to add the extension? just some thoughts.

Hope that helps,

Andy
Hi,
The program instructions require that the user input the file name. Also, the book we are using hasn't covered any use of ::
Is there any way to code it without that?

Thank you
I would would read the filename in main as you do, create the stream and open it it.
Then you pass it to to readFile and read the data.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main()
{
    const int ARRAY_SIZE=12;
    int numbers[ARRAY_SIZE];
    string fileName;
    cout << "Please enter the name of the file to read numbers for Number Analysis Program:";
    cin >> fileName;
    ifstream src(filename.c_str());
    if (!src)
    {
       // handle error
       // return 1;
    }
    readFile(src, numbers, ARRAY_SIZE); 
    
    return 0;
}
Hi,
Thanks for the suggestion, but we also didn't cover anything for the "filename.c_src())" format. Or anything with src.

Andy,
The input file I'm using is a text file with the following 12 numbers, each in a separate line.
47
89
65
36
12
25
17
8
62
10
87
62
Last edited on
So I wrote "inputFile" as the input for the cin prompt, and it worked. Below is the entire code. The output was the cout statements, the cin prompt, and the total (520) which is correct for that list of numbers I provided. However, I want this result when the user types in "numbers.txt", not inputFile. How can I achieve this?

Thanks
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

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

void readFile(ifstream &, int [], int); //Function prototypes.



int main()
{
    const int ARRAY_SIZE=12;
    int numbers[ARRAY_SIZE];
    string fileName;
    cout << "Please enter the name of the file to read numbers for Number Analysis Program:";
    cin >> fileName;
    ifstream src(fileName.c_str());
    if (!src)
    {
        // handle error
        // return 1;
    }
    readFile(src, numbers, ARRAY_SIZE);
    
    int total = 0; // Initialize accumulator
    for (int tot = 0; tot <ARRAY_SIZE; tot++)
        total += numbers[tot];
    cout << "The total is" << total << ".\n";
    
    return 0;
}

void readFile(ifstream &inputFile, int nums[], int size)
{
    int count=0;
    inputFile.open("numbers.txt");
    while (count < size && inputFile>>nums[count])
        count++;
    if (!inputFile)
        cout << "Error opening the file." << endl;
}


Hello ayleeta,

Thank you for the input file.

Sorry for the delay. I had to restart my computer and get back to what I was working on.

I figured that was part of the assignment to have the user enter a file name. Think back if the entered file name is for an out file this is not a problem because it will be created if it does not exist. For an input file the user will have to enter the full complete file name with extension. Without something to look at a user could get the file name wrong. Just saying that you and your program need to account for this.

The '::' I think you are referring to would be "std::". This is what you need to use to qualify what is in the standard name space when you do not use the line using namespace std;.

I hat to say this, but if you are paying for you class you are paying for someone to teach you the wrong way of doing things. Yes the using statement does make typing easier, but not better. Eventually you will need to qualify what is in a name space and you will have to learn it all at one time. Whereas now it is a little at a time. In order to code without using "std::" you are already the needed using statement.

Give me a little time to catch up and I will let you know what I find.

Hope that helps,

Andy
Hello ayleeta,

In main the line ifstream src(fileName.c_str()); not only creates "scr" as an "ifstream" it also opend the stream. So when you pass "scr" to the function you are trying to open the same open file stream with another name and it fails.

You are asking for a file name in main, but the function actually opens the file stream and never sees the file name thet you have taken from the user. Then in the function you are using a completely different file name than what the user entered.

Just so you know what is happeningifstream src(fileName.c_str());. "fileName" is defined as a string and the ".c_scr()" is a function of the string class to convert the string to a C string. This is needed before C++11 standards. From C++11 on a "std::string" is allowed for opening a file stream. Unless your compiler is old you will not need this.

This is your program that I have made some changes to and added some useful code that you can use:
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
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <chrono>
#include <thread>

using namespace std;

void readFile(ifstream &, int[], int); //Function prototypes.

int main()
{
	const int ARRAY_SIZE = 12;  // <--- Put this above main and you will not have to pass it to functions.
	int numbers[ARRAY_SIZE];
	string fileName;

	cout << "Please enter the name of the file to read numbers for Number Analysis Program:";
	cin >> fileName;

	ifstream src(fileName);  // <--- Creates file stream and opens file.

	if (!src)
	{
		std::cout << "\n Error opening file \"TextFile1.txt\"" << std::endl;
		std::this_thread::sleep_for(std::chrono::seconds(3));  // Requires header files "chrono" and "thread"
		exit(1); // <--- I like using exit here. return also works.
	}

	readFile(src, numbers, ARRAY_SIZE);

	int total = 0; // Initialize accumulator

	for (int tot = 0; tot < ARRAY_SIZE; tot++)
		total += numbers[tot];

	cout << "The total is" << total << ".\n";

	// This next line may not be needed. If you have to press Enter to see the prompt then comment out the
	// next line. If not you will need this to clear the input buffer first.
	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
	std::cout << "\n\n Press Enter to continue";
	std::cin.get();

	return 0;
}

void readFile(ifstream &inputFile, int nums[], int size)
{
	int count = 0;

	inputFile.open("numbers.txt");  // <--- Stream already open. This does not work.

	if (!inputFile)  // <--- Moved this up. Should be done first. I would also change the statements ot match what I did above.
		cout << "Error opening the file." << endl;

	while (count < size && inputFile >> nums[count])
		count++;
}

Do not worry about the last two header files. You really do not need to know much about them just that they need to be there as the line of code that used them tells you.

And this is the way I might have written the program. I would have done some thing slightly different, but I used as much of what you started with as I could.

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

using namespace std;

const int ARRAY_SIZE = 12;  // <--- Put this above main and you will not have to pass it to functions.

void readFile(int numbers[]); //Function prototypes.

int main()
{
	int numbers[ARRAY_SIZE];

	readFile(numbers);

	int total = 0; // Initialize accumulator

	for (int tot = 0; tot < ARRAY_SIZE; tot++)
		total += numbers[tot];

	cout << "\n The total is " << total << ".\n";

	// This next line may not be needed. If you have to press Enter to see the prompt then comment out the
	// next line. If not you will need this to clear the input buffer first.
	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
	std::cout << "\n\n Press Enter to continue";
	std::cin.get();

	return 0;
}

void readFile(int nums[])
{
	string fileName;
	int count = 0;
	ifstream inputFile;

	cout << "\n Please enter the name of the file to read numbers for Number Analysis Program: ";  // <--- Added '\n' and a space at the end.
	cin >> fileName;

	inputFile.open(fileName);  // <--- Stream already open. This does not work.

	if (!inputFile)
	{
		std::cout << "\n Error opening file \"TextFile1.txt\"" << std::endl;
		std::this_thread::sleep_for(std::chrono::seconds(3));  // Requires header files "chrono" and "thread"
		exit(1); // <--- I like using exit here. return also works.
	}

	while (count < ARRAY_SIZE && inputFile >> nums[count])
		count++;
}


Hope that helps,

Andy
Hi Andy,
Thank you so much! Using your comments, I was able to fix the code. I've posted it below in case anyone comes upon this topic with a similar problem.

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>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;

void readFile(ifstream &, int [], int); //Function prototypes.

int main()
{
    const int ARRAY_SIZE=12;
    int numbers[ARRAY_SIZE];
    string fileName; //For user file input

    cout << "Please enter the name of the file to read numbers for Number Analysis Program:";
    cin >> fileName;
    ifstream src(fileName,ifstream::in);
    if (!src) //Input validation
    {
        cout << "Error opening the file." << endl;
    }
    else
    {
    readFile(src, numbers, ARRAY_SIZE); //Call function 1    
    }
    return 0;
}

//Define function 1
void readFile(ifstream &inputFile, int nums[], int size)
{
    int count=0;
    while (count < size && inputFile>>nums[count])
        count++;
}
Last edited on
Hello ayleeta,

Very good and much better.

Watch your indenting and some blank lines will make it easier to read. The compiler does not care about white space in the code other than when defining variables.

A note: on line 17 you define "scr" as type "ifstream". Since this is defined as an input stream the "ifstream::in" is not needed. This is only needed if "scr" was defined as an "fstream" which has no default and you have to tell it which type of stream it needs to be, e.g., in or out.

Andy
Topic archived. No new replies allowed.