Can I call the function like that? - c++

If I have a struct.
struct studentRec
{
string name;
int sid;
string major;
int cohort;
};
Then, I have a function.
int compare_MajorName(const studentRec& s1, const studentRec& s2)
Can I call the function like that?
String major = ECE;
list = new studentRec[n];
compare_MajorName(list[mid], major)

No you can't.
Your function parameters require studentRecs. A String cannot be converted to a studentRec automagically. It wouldn't make sense.
You have two possibilities:
make an overrided function which accepts a String as a second parameter
simply compare the name inside the struct with your String:
list[mid].name == major for exemple

Related

Pointer pointed to string passed by function in C++

I have a question on the pointer used by string in a function. my code is below.
void printName(int *max,int *min,string *maxFirst, string *maxLast)
{
ifstream infile;
infile.open("input.txt");
string firstName,lastName;
float age;
infile>>firstName>>lastName;
while(firstName!="Term") {
infile>>age;
if(age==*max)
{
maxFirst=&firstName;
maxLast=&lastName;
cout<<*maxFirst<<' '<<*maxLast<<endl;
}
}
To use this function, in main(), I define it like
int main()
{
void printName(int *,int *,string *,string *);
int *pMaxAge, *pMinAge;
string *maxFirst,*maxLast;
pMaxAge=&maxAge;
pMinAge=&minAge;
printName(pMaxAge,pMinAge,maxFirst,maxLast);
cout<<"\nThe oldest employee is "<<*maxFirst<<' '<<
*maxLast<<endl;
}
I skip some part of my code. While the first cout works fine, the second one doesn't work. Is there any problem with my pointer passing please?
Thanks.
Your understanding of pointers is a complete mess. You should go and RTFM on pointers, from the ground up. Nothing you do here makes sense.
First you declare 4 pointers, not initialized to anything. Then you pass them to a function which takes pointer arguments by value, and expect changing the pointers' values to affect anything outside the function.
You should allocate these variables in your main function, and then pass them either by reference or by address, and assign to them properly when doing so.
For instance:
void printName(int *max,int *min,string *maxFirst, string *maxLast)
{
ifstream infile;
infile.open("input.txt");
string firstName,lastName;
float age;
infile>>firstName;
while(firstName!="Term") {
infile>>lastName>>age;
if(age==*max)
{
*max = (int)age;
*maxFirst=firstName;
*maxLast=lastName;
cout<<*maxFirst<<' '<<*maxLast<<endl;
}
infile>>firstName;
}
}
int main()
{
int MaxAge = 0, MinAge;
string maxFirst,maxLast;
printName(&MaxAge,&MinAge,&maxFirst,&maxLast);
cout<<"\nThe oldest employee is "<<maxFirst<<' '<<
maxLast<<endl;
}
In the printName function you need to assign to the content of the pointer:
*maxFirst = firstName;
*maxLast = lastName;
You also need to pass pointers to the existing variables as function arguments:
string maxFirst;
string maxLast;
printName(pMaxAge, pMinAge, &maxFirst, &maxLast);
The same probably applies to the integer arguments.

C++ Passing a function that's in a class to another function

I'm trying to use lua_pushcfunction (Using lua 5.2). I have the struct
class readFunctions {
private:
std::ifstream file;
public:
static int readAll(lua_State*);
};
int readFunctions::readAll(lua_State *L){
std::string line;
std::string nam;
while (std::getline(file, line)) {
nam = nam + line;
}
std::cout << nam;
return 1;
}
readFunctions hand;
I use lua_pushcfunction(lua_state, hand.readAll) and get error: argument of type 'int (readFunctions::)(lua_State*)' does not match 'lua_CFunction {aka int (*)(lua_State*)}'|
How would I pass a method from a class to a function?
Try
lua_pushcfunction(lua_state, & readFunctions::readAll);
readAll is static so you dont need an instance; and you need its address not just the function (a function is like a value, so you need to give pushcfunction its address). However I can't remember if compiler will accept int (readFunctions::*)(lua_State*) as a int (*)(lua_State*), I have a feeling it might not but can't test it right now.
If you don't want a static method but a regular method: the method is part of an object (class instance), so to call it you need a this pointer; that won't work. But what might work is to use your static readFunctions::readAll, but when you call that function, the first parameter can be a light user data that is the readFunctions instance that you want to call.

Copy string value into a class field?

I'm new to and learning C++. I know a fair amount of Java and some C.
What I want to do is to create an immutable name class that takes in a string value, copies that string to a class field and then eventually hashes it to an ID that can be parsed much more efficiently than a string.
I'm hitting a wall due to a general lack of knowledge of C++ strings. Here's what I have so far...
#pragma once
#include <string>
class Name
{
public:
Name(std::string s);
~Name(void);
int getId();
std::string getName();
private:
int id;
std::string name;
};
and...
#include "Name.h"
Name::Name(std::string s)
{
}
So what I want to do is store the value of s, passed in by the constructor in the "name" private field. As far as I know a new string object must be created and then the value of s must be copied into it.
I also think that the argument s can and should be a string pointer instead of a string object (to prevent an unnecessary copy from occurring). If I'm right then the constructor should look like the following, right?
Name::Name(std::string &s) { ... }
In this case, nothing would need to be done special when passing in a name? IE.
Name n = new Name("Cody");
is perfectly valid? Actually I'm not sure since "Cody" to my knowledge is a constant string or something like that.
So if I'm all on the right track, then what is the proper way to actually copy the value? I'm thinking this is appropriate but I'm not sure.
#include "Name.h"
Name::Name(std::string s)
{
name = new string(s);
}
Thanks for the help in advance, I know it's a basic question but I'm slowly making baby steps into the C++ world. :) - Cody
You are close, your code can be like this after a little massage:
class Name
{
public:
Name(const std::string& s); // add const and reference
~Name(void);
int getId() cosnt; // add const
std::string getName() const; // add const
private:
int id;
std::string name;
};
Name.cpp
Name::Name(const std::string& s):name(s)
{
}
Here :name(s) is called member initializer list.
Name n = new Name("Cody"); is perfectly valid? Actually I'm not sure
since "Cody" to my knowledge is a constant string or something like
that.
No, n is not pointer, it's not like java you need to new for every object. In C++, you do
Name n("Cody");
This will call Name(const std::string& s) to initialize object n and initialize name string with "Cody".
Note: variable n has automatic storage duration, it will be destroyed if it goes out of scope.
To let n on dynamic storage duration, you need to use new/delete pair:
Name *pn = new Name("Cody");
delete pn;
or use smart pointers, you no need to call delete n_ptr; as n_ptr will be destroyed when it goes out of scope as well:
#include <memory>
std::shared_ptr<Name> n_ptr(new Name("Cody"));
EDIT:
To use Name class in other classes, it's the same way when you use string in Name class, you don't have to use pointers.
class TestName
{
public:
TestName(const Name& n):name_(n){ }
private:
Name name_;
};
TestName tn("Cody");
You should use a constant reference to std::string here.
As you said, it would prevent unnecessary copies.. But then why not just a pointer or a constant pointer?
A constant reference would allow you to pass to your function some arguments that would implicitly call the right std::string constructor.
So, in a nutshell, you could do that:
Name::Name(const std::string& s)
{
this->name = s;
}
// Or even better..
Name::Name(const std::string& s):
name(s)
{
}
int main(void)
{
Name nick("hello");
return 0;
}
You can find out about every std::string's constructors on its cplusplus.com's sheet.

Passing user input to function with char* parameters

I'm new to this so I know this is probably something simple.
I have a function like this
void GroceryList::addRecord(char* itemName, char* itemType, char rating){
//do some code;
}
My problem is I am having trouble creating proper arguments to pass to the function.
I've tried something like
void main() {
string itemName;
cin >> itemName;
string itemType;
cin >> itemType;
string rating;
cin >> rating;
gradeBook.addRecord(itemName, itemType, rating);
}
I didn't expect it to work as the function is expecting char* but I can't for the life of me figure out how to get the user input into a variable that I can pass to the function. I've been search for literally 13 hours trying what I can find but no luck so far.
Well, don't use char*.
void GroceryList::addRecord(const std::string& itemName, const std::string& itemType, const std::string& rating) { /* ... */ }
You can get const char* (not char*) from string with c_str() member function, e.g. itemName.c_str(), but unless you're doing interop with C libraries, you don't need that.
Change the function prototype to
void GroceryList::addRecord(string itemName, string itemType, string rating){
//do some code;
}
I also recommend const correctness in your code, if you are not going to change the arguments, pass them by ref with const (for performance)
void GroceryList::addRecord(const string& itemName, const string& itemType, const string& rating){
//do some code;
}
All depends on the actual method body which you didn't describe.
Use std::string::c_str(); that's what it's for:
gradeBook.addRecord(itemName.c_str(), itemType.c_str(), rating.c_str());
This function returns a const char *. However, the addRecord function doesn't seem to be const-correct, so you need to fix that.
You can use string and then when passing just call c_str() on the string. For the rating you can just use a char.
Then calling the function looks like:
gl.addRecord(itemName.c_str(), itemType.c_str(), rating);
For this to work you'll need to change the function signature to const char* instead of char*.
The simple answer is that you can't. If you can modify
GroceryList::addRecord, change it to use std::string const&. If you
can't modify it, then you have to ask the question: why does it use
char*? There are two possible answers: the author didn't understand
const, or was too lazy to use it, and in fact doesn't modify the
pointed to strings. In this case, something like
const_cast<char*>( itemName.c_str() ) can be used; it's wordy, but
that's the price you pay when the code's author doesn't do his job
correctly. The other possible answer is that the code does modify
something through the pointer. In this case, the only solution involves
making a copy of the string into a char[], and passing it.

Calling functions and returning values

I am a beginner in C++.I have a function which returns some parameters that i need ,to use in the rest of my program.I am trying to access that function within another class.I am confused with the way i can do it...Can anyone please help me..?
Following is my code :
void SampleProgram :: myFunction()
{
string sInput;
GetInfo getInfo(sInput); //creating instance of the class containing the function
string sSw="";
string sName="ram";
string sList="list";
getInfo.getRequiredInfo(sSw,sName,sList); //calling the function
}
How can i access the output parameters of getRequiredInfo() ..?and save it if the ouput parameters are as following :string name,int status
Please help me...
You'd have to show us the declaration of getRequiredInfo(), but presumably it's something like
X result = getInfo.getRequiredInfo(sSw,sName,sList);
We don't know what X is without seeing that declaration.
In case getRequiredInfo get the address of the strings, try this:
getInfo.getRequiredInfo(&sSw, &sName, &sList);
Now the function can change the value of the arguments.
You can able to return single value in function.
so You can create struct containing string and int and return that as the result.
struct
{
string name;
int k;
}result;
result r = getInfo.getRequiredInfo(sSw,sName,sList); //calling the function
you can save the output parameters like these:
string _name;
int nk;
_name = r.name;
nk = r.k;
The simplest would be return a pair<string,int> from the function. So your function signarutre would be pair<string,int> getRequiredInfo(const string& s1, const string& s2, constr string& s3);. You can then access the string and int part usinf first and second members of the pair.
It sounds as though getRequiredInfo has the behaviour of both reading from and writing to some of the parameters you've passed in.
In C++, unlike in C#, there's no way to specify that a function should, or must, change the value of a given parameter. Indeed, if you have defined your function like this:
void GetInfo::getRequiredInfo(string a, string b, string c);
then all three parameters will be passed by value meaning any changes made to them inside the function will be changing copies of those objects, rather than the objects themselves.
As other contributors have suggested, if you really want to change the parameters you passed in, you could either do so by passing references:
void GetInfo::getRequiredInfo(string a, string& b, string& c);
or (more typically) by passing pointers:
void GetInfo::getRequiredInfo(string a, string* b, string* c);
However, if you want your function to simply read the parameters and return a value (which is the more accepted term for what you're calling 'output parameters') then you have to express your tuple of "name + status" as a single value.
You could use the built in pair template as someone else just suggested:
pair<string,int> getRequiredInfo(string a, string b, string c);
Or you could define your own struct to do it, like someone else suggested:
struct NameAndStatus
{
string name;
int status;
};
NameAndStatus getRequiredInfo(string a, string b, string c);