Sort or Mergesort based on user input - c++

I am trying to call a function based on user input. I cannt figure out what I am doing wrong. I keep getting this error
error: no matching function for call to 'sort(std::vector<int, std::allocator<int> >&)'
Can someone tell me what I am doing wrong. Please explain any suggestions thoroughly as I am brand new to C++. Here is my code:
#include <iterator>
#include <algorithm>
#include <vector>
#include <fstream>
#include <iostream>
#include <string>
std::ifstream in("");
std::ofstream out("outputfile.txt");
std::vector<int> numbers;
std::string sortType = "";
std::string file = "";
int main()
{
std::cout << "Which type of sort would you like to perform(sort or mergesort)?\n";
std::cin >> sortType;
std::cout << "Which file would you like to sort?\n";
std::cin >> file;
//Check if file exists
if(!in)
{
std::cout << std::endl << "The File is corrupt or does not exist! ";
return 1;
}
// Read all the ints from in:
copy(std::istream_iterator<int>(in), std::istream_iterator<int>(),
std::back_inserter(numbers));
//check if the file has values
if(numbers.empty())
{
std::cout << std::endl << "The file provided is empty!";
return 1;
} else
{
if(file == "sort")
{
sort(numbers);
}else
{
mergeSort();
}
}
}
void sort(std::vector<int>)
{
// Sort the vector:
sort(numbers.begin(), numbers.end());
unique(numbers.begin(), numbers.end());
// Print the vector with tab separators:
copy(numbers.begin(), numbers.end(),
std::ostream_iterator<int>(std::cout, "\t"));
std::cout << std::endl;
// Write the vector to a text file
copy(numbers.begin(), numbers.end(),
std::ostream_iterator<int>(out, "\t"));
std::cout << std::endl;
}
void mergeSort()
{
//mergesort code..
}

You need to declare the sort function before you call it. Move its definition above main, or put void sort(std::vector<int>); before main.
And the same goes for mergeSort.
You should also fully qualify the call sort(numbers.begin(), numbers.end()); as std::sort(numbers.begin(), numbers.end());, and the same for copy, unique. If you don't, then for technical reasons called "ADL", which you can look up if you like, then the call only compiles if the arguments that you're calling it on (the iterators) are classes in namespace std. It's up to the specific implementation whether or not they are, so the call won't work on some compilers.

I agree with #steve on declaring sort function before main().
I think the problem here is that you're calling the sort() function with parameter std::vector but in definition of the function you just wrote the type of received parameter, you should also write some name for the variable. eg.
void sort(std::vector<int> <variable_name>)
{
//definition
}
One more thing I want to point out is that as you have declared the vector number globally then there is no need to call the like sort(number), because function will automatically find the globally defined vector number. So basically if you want the vector number to be defined globally then the function sort() should be parameterless.
you have also used scope std:: everywhere, instead you can just add one line right after the #includes -
using namespace std;
I hope it works!

Related

Trying to get to grips with C++ and cant work out why this doesn't print out the names of the vector<string> entries

So this code doesn't print out the entries inside of the vector gameLibrary
Originally I just used the gameLibrary.pushback(" ") function to add them and that worked fine.
I'm more just trying to get to grips with why this doesn't work. when ( at least in my mind it's doing the same thing)
#include <iostream>
#include <vector>
#include <string>
using std::cout;
using std::vector;
using std::string;
void addGame(vector<string> gameLibrary, string gameName);
int main()
{
vector<string> gameLibrary;
vector<string>::iterator editIter;
addGame(gameLibrary, "game");
addGame(gameLibrary, "game 2");
cout << "Your library: " << std::endl;
for (editIter = gameLibrary.begin(); editIter != gameLibrary.end(); ++editIter)
{
cout << *editIter << std::endl;
}
return 0;
}
void addGame(vector<string>gameLibrary, string gameName)
{
gameLibrary.emplace_back(gameName);
}
addGame must not receive the vector it is filling by copy. It must be passed by reference or by pointer.
Exemple passing by reference :
void addGame(vector<string>& gameLibrary, string gameName)
{
gameLibrary.emplace_back(gameName);
}
Otherwise, the copy is modified, so the vector declared in main is unchanged.
Please read up on passing by value vs reference. In your function you are passing your array by value, which means that only the value of your array gets copied into the function.
Any changes to the array insider the function are not reflected back. If you need that, you need to pass your array by reference
see this answer : Are vectors passed to functions by value or by reference in C++

C++ class getter not returning any value in main, but does in the class?

I am hoping someone can point me in the direction, why my getter function cannot seem to be accessed properly when it is used outside the function in which the setter is declared.
I am reading in a file, storing variables of each line using the getline function, and then assigning the message to a private variable in Message.h.
When I cout the m1.getmessage() in within the readfile() function it outputs absolutely fine, with the correct output (The message line from my text file), however it just gives blank output in the main(). I've been trying to get my head around it for quite a few hours now, I have been reading about local variables but as far as I can see the variable is already set, and in a public function, therefore I can't see where I'm going wrong. Any help would be really appreciated before I reach for the vino at 4am.
Message.h
#include <iostream>
class Message {
private:
std::string message;
std::string cipher;
public:
void readFile();
void setMessage(std::string msg) {
message = msg;
}
void setCipher(std::string ciph) {
cipher = ciph;
}
std::string getMessage() {
return message;
}
std::string getCipher() {
return cipher;
}
};
Message.cpp
#include "Message.h"
#include <fstream>
#include <iostream>
void Message::readFile() {
std::string fileUsername;
std::string fileForename;
std::string fileSurname;
std::string fileAge;
std::string fileTime;
std::string fileHour;
std::string fileMin;
std::string fileSec;
std::string fileCipher;
std::string fileMessage;
Message m1;
std::fstream file;
std::string filename;
std::cout << "Please enter file name: " << std::endl;
getline(std::cin, filename);
file.open(filename);
if (file.is_open()) {
std::cout << "File opened" << std::endl;
} else {
std::cout << "Wrong file name" << std::endl;
}
while(file.is_open()) {
getline(file, fileUsername);
getline(file, fileForename);
getline(file, fileSurname);
getline(file, fileAge);
getline(file, fileHour, ':');
getline(file, fileMin, ':');
getline(file, fileSec);
getline(file, fileCipher);
getline(file, fileMessage);
file.close();
}
m1.setMessage(fileMessage);
m1.setCipher(fileCipher);
m1.getMessage();
};
Main.cpp
#include <iostream>
#include <iomanip>
#include <fstream>
#include "Message.h"
#include "Caesar.h"
#include "XOR.h"
int main() {
Message m1;
m1.readFile();
std::cout << m1.getMessage();
return 0;
}
The cout in the main is returning nothing, whereas if I transfer it into m1.readfile() it outputs the variable perfectly.
This is my first attempt at object orientated programming and it's definitely my weak spot. Thanks in advance for any advice.
In the Message::readFile() function, you are not calling the functions setMessage and setCipher on the current object, but on a local variable m1. The local variable is discarded at end of the function and the message and cipher don't end up getting saved. You should instead just call
setMessage(fileMessage);
setCipher(fileCipher);
getMessage();
instead of
m1.setMessage(fileMessage);
m1.setCipher(fileCipher);
m1.getMessage();
This will update the message and cipher variables of the current object and you can then print getMessage() from the main function.
you create a local variable m1 in readfile. And then it gets discarded when the function ends. Probably you want to either return the object, or set the current instance
You don't have to create an object inside that class's member function
My suggestion:
Omit / Remove Message m1; in the readFile()
Directly call the fuctions as
setMessage(fileMessage);
setCipher(fileCipher);
getMessage();
You can use this; pointer to object that your currently working on.
like below.
this->setMessage(fileMessage);
or
(*this).setMessage(fileMessage);

Iterating over list of pairs, the list being in an array

I have searched the farthest reaches of the universe (aka the internet) and have not found a single hint as to how to solve my problem. So I come to you.
I am trying to iterate over a list that contains pairs of strings.
This list is one of 20 inside an array.
this is my current code:
logging.h:
#ifndef LOGGING_H
#define LOGGING_H
#include <iostream>
#include <list>
#include <string>
class logging
{
public:
void log(int,std::string,std::string);
void draw();
logging();
virtual ~logging();
private:
int displaylevel=0;
std::list<std::pair<std::string,std::string>> logd[20];
};
#endif // LOGGING_H
logging.cpp:
#include "logging.h"
#include <list>
#include <string>
#include <iostream>
logging::logging(){
//for future use
}
void logging::log(int level,std::string category, std::string entry) {
int thislevel;
for (thislevel=level-1;(thislevel>-1);thislevel--){
std::pair <std::string,std::string> newentry;
newentry = std::make_pair (category,entry);
logd[thislevel].push_front(newentry);
}
}
void logging::draw(){
//draw console on the screen using opengl
std::list<std::pair<std::string,std::string>>* log = &(logd[displaylevel]);
std::list<std::pair<std::string,std::string>>::iterator logit;
for ( logit = (*log).begin() ; logit != (*log).end() ; logit++ ) {
std::cout << (*logit).first() << std::endl << (*logit).second() << std::endl;
}
}
logging::~logging() {
//Deconstructor for log class (save log to file?)
}
The idea is that if an event of importance 5 is logged, then it gets put in list 0,1,2,3 and 4. that way various verbose levels can be shown in game (if the console/log is open) by simply displaying the list corresponding to that verbose level (defined by displaylevel). however I cant seem to be able to iterate over the list properly, it keeps throwing a no match for call to std::basic_string error. Any help is appreciated, I am very new to C++.
first and second are member variables of std::pair not member methods. Drop the parentheses:
std::cout << (*logit).first << std::endl << (*logit).second << std::endl;
You don't need () to access the .first and .second of std::pair members. They're variable members, not methods.
Remove them:
std::cout << (*logit).first() << std::endl << (*logit).second() << std::endl;
^^ ^^
first & second are not member functions. You cannot use them like a function. Remove the parentheses. Also instead of making logd an array, you can use a vector something like this
std::vector< std::list< std::pair< std::string, std::string > > > logd;
Also it will prevent the unnecessary allocation of memory.

How do I pass a string into a function?

I am attempting to use an overloaded function to get a string.
void get(char prompt[], int size,const std::string b = "")
{
std::cout << prompt << ": ";
std::cin.get(b, size);
std::cin.ignore(10, '\n');
}
Now I did just change the last argument from a character array to a string at the advice of another poster on this site, so I'm a little lost. I'm getting error message at the '.' in between cin and get. I've also tried cin.getline (I have no idea if there's a difference or what it is)
Error message : cannot convert parameter 1 from 'const std::string' to
'char *'
The error has a lot of other stuff, but I think that's the important bit.
I'm indirectly answering your question by suggesting an alternative method. Here's my implementation, along with an example of how to use it.
#include <string>
#include <iostream>
#include <ostream>
std::string get(std::string const& prompt)
{
std::string ret;
std::cout << prompt << ": ";
getline(std::cin, ret);
return ret;
}
int main()
{
std::cout << get("Please enter your answer") << std::endl;
// or
std::string prompt("Enter your answer");
std::string response = get(prompt);
std::cout << response << std::endl;
}
When working with strings, you need to use the free function getline from the string header, not the member function getline from iostream. So it would be std::getline(std::cin, b);.
That being said getline won't accept a const string as its argument for the simple reason that the whole point of calling getline is to write to the string. Also note that unless you make b a (non-const) reference, any changes you perform on b inside your get method will not be visible outside of the method since strings are copied if you pass them by value.
The difference between istream::get(char*, streamsize) and istream::getline(char*, streamsize) is that the latter discards the newline character (as does the getline method for strings) while the former does not.
http://www.cplusplus.com/reference/iostream/istream/get/
http://www.cplusplus.com/reference/iostream/istream/ignore/
your call to get() doesn't match any of the existing istream methods. it just may end up being recursive if it ever works?
#include <string>
namespace std {
//I am attempting to use an overloaded function to get a string.
class Ciostream : public iostream {
public:
void get(char prompt[], int size,const std::string b = "")
{
cout << prompt << ": ";
cin.get(b, size);
cin.ignore(10, '\n');
}
};
}
//1.cpp:11:28: error: no matching function for call to 'std::basic_istream<char>::get(const string&, int&)'

C++: Keep track of times function is called

Keeping track of how many times a function is called is easy when passing the counter as an argument into the function. It's also easy when returning a one from the called function. But, I do not want to go that route. The reason behind this is because it seems like bad programming (letting the function know too much information). Is there a better way to keep track of how many times this function has been called?
I'm just looking for concepts that I could study. Providing code examples is not neccessary, but might be helpful.
Edit: I'm not actually looking for profiling tools. Let me add some code to get my point across. Because scope for funcCounter ends in main, I have no way of getting back a variable from myFunction that will increment funcCounter. I could possibly return 1 from myFunction and then increment funcCounter that way, but this doesn't seem like very good programming. Is there another way to do it?
int main()
{
int funcCounter = 0;
char *mystring = "This is a silly function.";
myFunction(mystring);
cout << "Times function is called: " << funcCounter << endl;
return 0;
}
void myFunction(char *mystring)
{
cout << mystring << endl;
}
Have a static variable in your function and keep incrementing it each time the function in called.
void my_Function(void) {
static unsigned int call_count = 0;
call_count++;
}
If you want to do it for debugging reasons, then there are tools like gcov which do this for you. (I'm pretty sure Microsoft doesn't have an alternative bundled with Microsoft Visual C++)
I would do this through the use of a profiling tool like gcov (which is for linux). These programs do the work of inserting code into your program during compilation and give you a report of how many times a function is called, where its called from, and how long the program spent executing that function.
It sounds like what you are looking for is a profiler. Depending on the platform you are using there are a slew of tools available that can help you hunt down the (ab)uses of a routine.
Please revise your question with the platform for which you need profiling tools.
If the function is part of a class, you can add a static counter to the class, plus an accessor and/or reset functions:
class X
{
private:
/* diagnostics */
static int counter = 0;
int read_counter() const { return counter; }
void reset_counter() { counter = 0; }
public:
/* real code */
fcn() {
++counter;
/* ... */
}
};
The problem with adding a static counter to a standalone function is that there's no way to get at the value.
You could add a global, of course, but instead of a raw global I'd suggest an instance of a singleton containing all your diagnostic code and data.
Use a class like this one, and simply instantiate it at the top of a function (or any other block) like is done in f() below.
Note: There is some overhead for gettimeofday() so you may want to use a different timing method, but that is a completely different topic worthy of it's own question (and has been addressed before on SO).
#include <iostream>
#include <string>
#include <map>
#include <sstream>
#include <ctime>
#include <cstdlib>
#include <sys/time.h>
class PerfStats
{
private:
std::string which_;
timeval begin_;
public:
PerfStats(std::string const &file, int line)
{
std::stringstream ss;
ss << file << ':' << line;
which_ = ss.str();
gettimeofday(&begin_, NULL);
}
~PerfStats()
{
timeval end;
gettimeofday(&end, NULL);
Times[which_] = (end.tv_sec - begin_.tv_sec) + (end.tv_usec - begin_.tv_usec)/1000000.0;
++Counts[which_];
}
static std::map<std::string, double> Times;
static std::map<std::string, unsigned int> Counts;
static void Print()
{
for(std::map<std::string, double>::iterator it = Times.begin(); it != Times.end(); ++it)
std::cout << it->first << " :\t" << it->second << "s" << std::endl;
for(std::map<std::string, unsigned int>::iterator it = Counts.begin(); it != Counts.end(); ++it)
std::cout << it->first << " :\t" << it->second << " times" << std::endl;
}
};
std::map<std::string, double> PerfStats::Times;
std::map<std::string, unsigned int> PerfStats::Counts;
void f()
{
PerfStats(__FILE__, __LINE__);
usleep(1);
}
main()
{
srand(time(NULL));
for(int i = 0; i < rand(); ++i)
f();
PerfStats::Print();
}
Sample output:
test.cpp:54 : 2e-06s
test.cpp:54 : 21639 times
Bad coding style, but maybe adding global variables and if necessary mutex locks may do the trick.