I'm creating a function template for a function "total" that keeps a running total of values entered. It takes two arguments, the number of lines of data it is to total, and the filename it is to open (there are three txt files, one with integer data, one with doubles and one with non-numbers.)
I am getting an error in line
total(n, file1);
"no matching function for call to total(int&, std::string&)"
Can anyone tell me what I'm doing wrong? Any help or advice would be much appreciated. Thank you!
#include <iostream>
#include <fstream>
#include <string>
usingnamespace std;
template <class T>
T total(int num, string filename)
{
T numbers;
T total;
T count = 0;
ifstream inputFile(filename);
//inputFile.open();
while ( (count++ < num) && (inputFile >> numbers) )
total += numbers;
if (count == num)
return total;
else
{
cout << "Error opening file.";
}
}
int main()
{
int choice = 0;
//Select the type of file
cout << "Choose the number of the file type you want to total:" << endl
<< "1. Integers\n2. Doubles\n3. Strings\n" << endl;
cin >> choice;
//Select the amount of data to read from the file (num/n)
if (choice == 1)
{
string file1 = "integers.txt";
cout << "How many lines of data would you like to total?";
int n = 0;
cin >> n;
total(n, file1);
}
if (choice == 2)
{
string file2 = "doubles.txt";
cout << "How many lines of data would you like to total?";
double n = 0.0;
cin >> n;
total(n, file2);
}
if (choice == 3)
{
string file3 = "not_numbers.txt";
cout << "How many lines of data would you like to total?";
int n;
cin >> n;
total(n, file3);
}
if (choice < 1 || choice > 3) {
cout << "Invalid choice. Enter integers, doubles or strings." << endl;
cout << "Choose the file type you want to total: integers, doubles, or strings.";
cin >> choice;
}
return 0;
}
#include <iostream>
#include <fstream>
#include <string>
template < class T > T total( int n, std::string filename)
{
T total{}; // total is value initialised (empty initializer):
// zero if T is an arithmetic type, or empty string if T is string
std::ifstream inputFile(filename);
T value ;
while( n>0 && inputFile >> value ) { total += value ; --n ; }
return total ;
}
int main()
{
std::cout << "Choose the number of the file type you want to total:\n"
<< "1. Integers\n2. Doubles\n3. Strings\n" ;
int choice = 0;
std::cin >> choice;
std::cout << "How many lines of data would you like to total?";
int n ;
std::cin >> n ;
if( choice == 1 )
{
const std::string file = "integers.txt";
std::cout << total<int>( n, file ) << '\n' ;
}
elseif( choice == 2 )
{
const std::string file = "doubles.txt";
std::cout << total<double>( n, file ) << '\n' ;
}
elseif( choice == 3 )
{
const std::string file = "not_numbers.txt";
std::cout << total<std::string>( n, file ) << '\n' ;
}
else std::cout << "Invalid choice. Enter 1 (integers), 2 (doubles) or 3 (strings).\n" ;
}
After solving the template issue, line 14 of the OP's code should be fixed.
The prototype of ifstream is basic_ifstream(constchar* __s, ios_base::openmode __mode = ios_base::in)
But filename is of type std::string {aka std::basic_string<char>}
So this must be converted to constchar * before passing to ifstream.
This does the trick ifstream inputFile(filename.c_str());
#include <iostream>
#include <fstream>
#include <string>
usingnamespace std;
template <class T>
T total(int num, string filename)
{
T total{};
T value;
ifstream inputFile(filename.c_str());
//inputFile.open();
while ( (num > 0) && (inputFile >> value) )
{
total += value;
--num;
}
return total;
}
int main()
{
//Select the type of file
cout << "Choose the number of the file type you want to total:" << endl
<< "1. Integers\n2. Doubles\n3. Strings\n" << endl;
int choice = 0;
cin >> choice;
cout << "How many lines of data would you like to total?";
int n;
cin >> n;
//Select the amount of data to read from the file (num/n)
if (choice == 1)
{
string file = "integers.txt";
total<int>(n, file);
}
elseif (choice == 2)
{
string file = "doubles.txt";
total<double>(n, file);
}
elseif (choice == 3)
{
string file = "not_numbers.txt";
total<string>(n, file);
}
else
cout << "Invalid choice. Enter integers, doubles or strings." << endl;
return 0;
}
If you've fixed all issues and dont see any value returned by total, its coz you dont use the value returned. In lines 42,48 and 54, it should be something like int x = total<int>(n,filename); //for case 1 .
Then you can use x.
Nice! That did the trick. You guys are awesome! Thanks for walking me through this. Thanks to everyone who posted for all the help, couldn't have done it without y'all.