using an index number, append that index (a character) to char array - c++

I'm attempting to do something like this.
class testClass {
public:
void testFunction(char charArray[])
{
char output[].append(charArray.at(1));
char output[].append(charArray.at(7));
char output[].append(charArray.at(3));
cout << output;
}
int main() {
testClass testObject;
testObject.testFunction("Flowers");
return 0;
}
}
What it's meant to do is:
get the Letters 'F', 'S' and 'O' from the char array from an index number
append that char to the output chararray
It's been frustrating since I've went from strings, to *chars, and char arrays.
Not really sure what the simpliest easiest solution is.
Yes, I want to retain 1 char at a time from that string.
It was just meant to be a fun project but it's way more complicated than I thought it'd be
expected output:
FSO

Do you mean like this:
#include <string>
#include <iostream>
class testClass {
public:
void testFunction(const std::string& charArray)
{
std::string output;
output.push_back(charArray.at(0));
output.push_back(charArray.at(6));
output.push_back(charArray.at(2));
std::cout << output;
}
};
int main() {
testClass testObject;
testObject.testFunction("Flowers");
return 0;
}
Of course C++ like any sane language uses zero-based indexes.

Related

Can't pass full array value to another function in C++

I am new to c++ & don't know the basics all that well. pls help (sorry if the solution to this is already available, but I couldn't find any)
This is the Error I am getting:
expected primary-expression before ‘]’ token
char CusName[50]=x[];
^
For this code below:
#include <iostream>
using namespace std;
class BankAccount
{
private:
char CusName[50];
char CusId[10];
float accBalance, dep, witd;
public:
void setCusDetails(char x[], char n)
{
char CusName[50]=x[];
}
};
int main()
{
BankAccount customer1;
char cus1Name[50];
cin>>cus1Name;
customer1.setCusDetails(cus1Name, 50);
return 0;
}
Your char array looks like a string. Try using std::string instead and prefer using const references for function parameters.
If you want to use char arrays, and if your point was to copy a null-terminated string by value, then use functions like strncpy.
Using std::string may be easier for you to hide the burden of memory allocation and discover the language step by step.
You can instead use string to input and pass values.
#include <iostream>
using namespace std;
class BankAccount
{
private:
string CusName; //CusName of type string
char CusId[10];
float accBalance, dep, witd;
public:
void setCusDetails(string str, char n) //parameter str of type string
{
CusName=str; //Assign it to the already declared 'CusName' variable.
}
};
int main()
{
BankAccount customer1;
string cus1Name;
cin>>cus1Name;
customer1.setCusDetails(cus1Name, 50);
return 0;
}

C String assigning values in explicit constructor in C++?

I have a class BankAccount with two string members - name and num. What I want is to assign values to these objects when I create them (when the constructor is called). However the compiler says No instance of constructor matches the argument list when I try to create an object.
I would like to ask why is that?
// hwk-2.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include "pch.h"
#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;
class BankAccout {
char name[23];
char num[15];
double sum;
public:
BankAccout(char *nm, char *nr, double s) {
strcpy(name,nm);
strcpy(num, nr);
sum = s;
}
};
int main()
{
BankAccout k("Peter", "0403940940", 34.21);
}
as a coffee break exercise here is more idiomatic version
#include "pch.h"
#include <iostream>
#include <string>
class BankAccount {
std::string name_;
std::string num_;
double sum_;
public:
BankAccount(std::string name, std::string num, double sum) {
name_ = name;
num_ = num;
sum_ = sum;
}
};
int main()
{
BankAccount k("Peter", "0403940940", 34.21);
}
The signature of the constructor does not match.
This one will match:
BankAccount(const char *nm, const char *nr, double s);
EDIT:
The reason is the way you are calling the constructor in the main function. You are giving literal strings as parameters. These literals are const, you cannot change them at runtime. Thus you will pass pointers to const char*.
This is very obvious if you look at this opposing example. This is a way that would be compatible with the old signature BankAccout(char *nm, char *nr, double s);.
int main(int argc, char* argv[])
{
char name[] = "hello";
char number[] = "1234";
std::cout << "name before: " << name << std::endl;
BankAccount k(name, number, 8.5);
// name and number are not const,
// you can change them :
name[2] = 'x';
name[3] = 'x';
std::cout << "name after: " << name << std::endl;
return 0;
}
An even simpler version, if you don’t need to have additional functionality in the class: just use a struct.
#include <string>
struct BankAccount {
std::string name;
std::string number;
double balance;
};
int main() {
BankAccount account{"Joy", "44", 43.};
}

Is it possible to modify function call with minimum code change?

I guess what I want to do is something like this (expressed like a marco).
#define x->send(str) x->send(my(x, str))
inside function "my"
char *my(X x, char *d)
{
strcat(d, x->name); // assuming no memory problem
}
Basically, need to attach more information about x. Of course, there are other ways around. But I want to keep minimum changes to the code, and there is no way to modify the X class. Thank you!
Sample code listed below.
#include <stdio.h>
#include <string.h>
#define x->send(y) (x->send(my(x,y)))
class H
{
public:
char name[16];
void send(char *str)
{
printf("%s", str);
}
H()
{
strcpy(name, "adam");
}
};
char *my(H x, char *y)
{
strcat (y, "from ");
return strcat(y, x->name);
}
int main()
{
H *h = new H;
char str[32];
strcpy(str, "hello ");
h->send(str);
return 0;
}
Use a wrapper class.
class DiagnosticH : public H {
public: void send(char *str) { H::send(my(this, str)); }
};
#define H DiagnosticH // optional
IF you can't modify X, I think the next best option is to do a regex replacement on your source to call your wrapper function instead. Even if it were possible to define a macro like that, it will lead to an unmaintainable nightmare.

How can I initialize char arrays in a constructor?

I'm having trouble declaring and initializing a char array. It always displays random characters. I created a smaller bit of code to show what I'm trying in my larger program:
class test
{
private:
char name[40];
int x;
public:
test();
void display()
{
std::cout<<name<<std::endl;
std::cin>>x;
}
};
test::test()
{
char name [] = "Standard";
}
int main()
{ test *test1 = new test;
test1->display();
}
And sorry if my formatting is bad, I can barely figure out this website let alone how to fix my code :(
If there are no particular reasons to not use std::string, do use std::string.
But if you really need to initialize that character array member, then:
#include <assert.h>
#include <iostream>
#include <string.h>
using namespace std;
class test
{
private:
char name[40];
int x;
public:
test();
void display() const
{
std::cout<<name<<std::endl;
}
};
test::test()
{
static char const nameData[] = "Standard";
assert( strlen( nameData ) < sizeof( name ) );
strcpy( name, nameData );
}
int main()
{
test().display();
}
Your constructor is not setting the member variable name, it's declaring a local variable. Once the local variable goes out of scope at the end of the constructor, it disappears. Meanwhile the member variable still isn't initialized and is filled with random garbage.
If you're going to use old-fashioned character arrays you'll also need to use an old-fashioned function like strcpy to copy into the member variable. If all you want to do is set it to an empty string you can initialize it with name[0] = 0.
Since you are using C++, I suggest using strings instead of char arrays. Otherwise you'd need to employ strcpy (or friends).
Also, you forgot to delete the test1 instance.
#include <iostream>
#include <string>
class test
{
private:
std::string name;
int x;
public:
test();
void display()
{
std::cout<<name<<std::endl;
}
};
test::test()
{
name = "Standard";
}
int main()
{
test test1;
test1.display();
std::cin>>x;
}
Considering you tagged the question as C++, you should use std::string:
#include <string>
class test
{
private:
std::string name;
int x;
public:
test();
void display()
{
std::cout<<name<<std::endl;
std::cin>>x;
}
};
test::test() : name("Standard")
{
}
c++11 actually provides two ways of doing this. You can default the member on it's declaration line or you can use the constructor initialization list.
Example of declaration line initialization:
class test1 {
char name[40] = "Standard";
public:
void display() { cout << name << endl; }
};
Example of constructor initialization:
class test2 {
char name[40];
public:
test2() : name("Standard") {};
void display() { cout << name << endl; }
};
You can see a live example of both of these here: http://ideone.com/zC8We9
My personal preference is to use the declaration line initialization because:
Where no other variables must be constructed this allows the generated default constructor to be used
Where multiple constructors are required this allows the variable to be initialized in only one place rather than in all the constructor initialization lists
Having said all this, using a char[] may be considered damaging as the generated default assignment operator, and copy/move constructors won't work. This can be solved by:
Making the member const
Using a char* (this won't work if the member will hold anything but a literal string)
In the general case std::string should be preferred

How should i randomly call class member methods?

I am writing a small "quiz program". It looks similar to this:
#include <cstdlib>
#include <iostream>
#include <time.h>
using namespace std;
using std::cout;
class cQuestion
{
private:
static short goodAnswers[20][2];
public:
static void checkAnswer(int questNumber)
{
/* checking input, checking if answer is bad or good */
/* putting the answer to cQuiz::answArr */
};
static void question1(void) { cout << "this is question 1"; };
static void question2(void) { cout << "this is question 2"; };
static void question3(void) { cout << "this is question 3"; };
static void question4(void) { cout << "this is question 4"; };
static void question5(void) { cout << "this is question 5"; };
/*and so on to question 20*/
};
short cQuestion::goodAnswers[20][2] = {0,0};
class cQuiz
{
private:
static short questArr[5];
static short answArr[5];
public:
void drawRandom(void)
{
srand ( time(NULL) );
for (int i = 0; i < 5; i++ )
questArr[i] = rand() % 20 + 1;
};
void askQuestions(void)
{
for (int i = 0; i < 5; i++ )
{
/* call questions by question number from questArr */
/* HOW SHOULD I CALL CERTAIN cQuestion CLASS MEMBER ?? */
cQuestion::checkAnswer(questArr[i]);
}
};
};
short cQuiz::questArr[5] = {0};
short cQuiz::answArr[5] = {0};
int main(int argc, char *argv[])
{
cQuiz quiz;
quiz.drawRandom();
quiz.askQuestions();
system("PAUSE");
return EXIT_SUCCESS;
}
I am wondering, how can (or should) I call class cQuestion member methods ? I was thinking about using an array of pointers to these members (cQuestion::question1, cQuestion::question2, and so on) or overloading subscript operator[].
I am not sure if either way is good or bad. Should i consider different solution or somehow use both together? Or am I completely missing the point?
This is not good design. Having to add a new method for each question means that you have to recompile each time you add aquestion to the quiz. And as you have found out, it is hard to call those functions randomly. A re-design is in order here.
Further to the OOP post above, how about:
class Question { // Make this a C++ interface
public:
Question(string q, string a)
: QuestionText(q), Answer(a)
{}
string QuestionText;
string Answer;
}
Then instantiate these using a factory or just in your initialisation function:
q1 = Question("What is the secret of life", "DNA");
q2 = Question("What is the answer to the great question", "42");
You should probably put these in a vector, rather than in local or global variables.
Apart from all the OOP dilemmas, maintain an array of function pointers to your member functions and randomly select one of them.
Why is each question in its own method? Why not make an array of strings to store the questions?
How about something like this?
string[] questions = {"Q1","Q2","Q3"};
void question(int i)
{
cout << questions[i];
}