C++ Char array not working - c++

I'm trying to get this program working, but get odd output. I know a char buffer is not ideal here, but it's for an assignment and not of my own design. Here's my code:
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
//Place your class definition here
class student {
public:
void inputData(int a, char s[20], float e, float m, float sci);
void printData();
private:
int admno;
char sname[20];
float eng;
float math;
float science;
float total;
float ctotal();
};
int main () //This is your main driver. Do NOT make any changes to it
{
student obj ;
int a;
char s[20];
float e, m, sci;
cin >> a;
cin.getline(s,20);
cin.clear();
cin.ignore(10,'\n');
cin >> e;
cin >> m;
cin >> sci;
obj.inputData(a, s, e, m, sci);
obj.printData();
return 0;
}
//Place your class member function definitions here
void student::inputData(int a, char s[], float e, float m, float sci) {
admno = a;
*sname = *s;
eng = e;
math = m;
science = sci;
total = ctotal();
}
void student::printData() {
cout << "Admission number: " << admno << endl << "Student name: ";
for (int i = 0; i < 20; i++)
cout << sname[i];
cout << endl << "English: " << eng << endl << "Math: " << science << endl << "Science: " << science << endl << "Total: " << total;
}
float student::ctotal() {
return (eng + math + science);
}
Here's my input:
98745
Kyle Smith
98
78
62
Here's the expected output:
Admission number: 98745
Student name: Kyle Smith
English: 98
Math: 78
Science: 62
Total: 238
Here's the actual output:
Admission number: 98745
Student name:  m ╩`uÄM■Å■   ║k`u
English: 98
Math: 62
Science: 62
Total: 238
Please give advice on how to fix. I have to stick with that char buffer, but don't know why I'm getting this corruption.
Thanks!

*sname = *s;
This copies one character, not the entire string. If you want to copy the entire string, you need to use std::strcpy
std::strcpy(sname, s);
or a loop
char* src = s;
char* dst = sname;
while (src) {
*dst = *src;
++src;
++dst;
}
Of course, you could do away with all of this manual string handling and use std::string instead:
//Place your class definition here
class student {
public:
void inputData(int a, std::string s, float e, float m, float sci);
void printData();
private:
int admno;
std::string sname;
float eng;
float math;
float science;
float total;
float ctotal();
};
void student::inputData(int a, std::string s, float e, float m, float sci) {
admno = a;
sname = std::move(s);
eng = e;
math = m;
science = sci;
total = ctotal();
}

Here is what happening:
cin >> a;
cin.getline(s,20);
cin.clear(); // never mind this, doesn't do anything in this context
cin.ignore(10,'\n');
Your int is read and stored in a
cin now contains \n left over after you pressed Enter
getline immediately attempts to read it into s but it discards it, s is now empty, but getline operation is complete.
Why does it still wait for the input of the name? Because cin.ignore is waiting for \n or at least 10 chars to be entered, but the stream buffer is now empty.
You enter your name and press Enter, ignore at least gets its \n and is now complete but your entered string is not stored anywhere. It is just ignored. If it wasn't ignored you would have gotten the 1st char of this string in the output, but you haven't.
Long story short, your input is broken. You should clear that \n after you entered the first number before getline. Only then, after you have your name stored in s you can attempt to pass it to the function, there is no point in passing a pointer to empty array and expecting it to work.

Related

C++ function and I/O file

I'm trying to get the numbers of lines of input file to be size of array, but it keeps giving error that expression of the array must be constant. Here is my code:
int main() {
int count = 0;
string line;
ifstream infile("students.dat");
while (getline(infile, line))
count++;
cout << "Numbers of input is: " << count << endl;
const int size = count;
double max, min, average;
int freshman, sophomore, junior, senior;
string firstname[size];
string lastname[size];
string year[size];
double grade[size];
cout << "name\n";
for (int i = 0; i < size; i++) {
infile >> firstname[i] >> lastname[i]
>> year[i] >> grade[i];
}
max = FindMax(size, grade);
cout << "\nHighest grade: " << max;
min = FindMin(size, grade);
cout << "\nLowest grade: " << min;
average = FindAvg(size, grade);
cout << "\nClass average: " << average;
FindYear(size, year);
infile.close();
return 0;
}
Sample input file:
John Omi freshman 66
Katy Hill sophomore 55
Jeff Ozco freshman 90
constant means compile-time constant, which means the compiler would know its exact value at compile time. For example:
10 // constant
#define VAL 10
VAL // constant
const int val = 10 + 1;
val // constant
The size in your code is a variable that its value is not known until the program runs and reads your file, counts its line. It is called a run-time variable.
This here is wrong:
size_t size = count; // obtain the number of elements
string firstname[size]; //< Fails with a compiler error
The declaration something[<size>] tells the compiler to generate space for <size> elements something. Since you know the number of elements (count) only at runtime, the compiler does not know what to do. The size parameter must be a (fixed) number, when the compiler translates your source into binary code.
That said: Please learn the std library. std is part of the C++ language!
Don't ever use [] for vectors/arrays anymore (unless in very specific instances).
The std library has a whole lot of containers that are very easy to use. The most prominent container is std::vector.
Rewrite your code, for example like this:
std::vector<std::string> firstname;
firstname.resize(count);
for (...)
infile >> firstname.at(i);
Or better still:
struct student
{
std::string firstname;
std::string lastname;
...
};
...
std::vector<student> students;
while (!infile.eof()) {
std::string first, last, this, that;
infile >> first >> last >> this >> that;
students.emplace_back(first, last, this, that);
// or alternatively
students.push_back(student(first, last, this, that));
Like I said: The std library is part of the C++ standard.

What is the correct syntax / format for entering information into the struct vector shown below

I am new to programming, and am trying to figure out one thing at a time.
What is the correct format for inputting information into the vector in line 13?
I am getting an error of StudentInformation has no member studentNames.
1 struct StudentInformation
2 {
3 std::string studentNames{};
4 int studentScores{};
5 };
6
7 void getInformation( int numberOfStudents, std::vector < StudentInformation> student )
8 {
9 for (int enterNameItterate{ 0 }; enterNameItterate = numberOfStudents; ++enterNameItterate)
10 {
11 std::cout << "Enter the name of the next student: ";
12 std::string studentName;
13 std::cin >> student.studentNames[enterNameItterate]{ studentName };
14 std::cout << "Enter the score of student: " << student.studentNames[enterNameItterate]{ studentName } << ": ";
15 int studentScore;
16 std::cin >> student.studentScores[enterNameItterate]{ studentScore };
17 }
18 }
You just want
std::cin >> student[enterNameItterate].studentNames;
If you dumb it down to just
std::string s;
std::cin >> s;
It might make it more obvious. The above code assumes you've already allocated the space for your vector, otherwise you would want this instead:
std::string studentName;
std::cin >> studentName;
int score = 0;
std::cin >> score;
student.emplace_back({studentName, score});
Something else that will quickly bite you on the bum: you're passing your vector into getInformation as a copy which means when you alter it within the function, you're not altering the actual object, but a copy of it. You can solve this by returning the vector of inputted information, or taking the vector by reference. Either:
std::vector<StudentInformation> getInformation(int numberOfStudents);
OR
void getInformation(int numberOfStudents, std::vector<StudentInformation>& student); // notice the &
I would change your structure slightly to provide a handy constructor function that takes a name and a score, e.g.
struct StudentInformation
{
StudentInformation() = default;
StudentInformation(const std::string& name, int score)
: name(name), score(score) {}
// renamed vars to something nicer.
std::string name{};
int score{};
};
I would change your function arguments slightly, so that you take a reference to an array of students. (Notice the '&' in the argument?)
void getInformation( int numberOfStudents, std::vector<StudentInformation>& students )
{
// simplifying the naming here. 'i' is generally known to be a counter.
for (int i = 0; i = numberOfStudents; ++i)
{
// some temp vars to store entered fields
std::string studentName;
int studentScore;
// get the data from the user
std::cout << "Enter the name of the next student: ";
std::cin >> studentName;
std::cout << "Enter the score of student: " << studentName << ": ";
std::cin >> studentScore;
// construct a new object at the end of the vector.
// this will call the constructor that takes two args
students.emplace_back(studentName, studentScore);
}
}

error: void value not ignored as it ought to be and error:return statement with a value

I'm working on a short code for my programming class and I can't figure out how to fix these two errors: "void value not ignored as it ought to be" and "return statement with a value, in function returning 'void'[ - f-permissive ]"
#include <iostream>
#include <math.h>
#include <stdlib.h>
void FutureValue(double, double);
using namespace std;
int main(int argc, char** argv) {
//Declare variables
int amount;
int newAmount;
int interestRate;
cout << "Please enter the dollar amount. " << endl;
cin >> amount;
cout << "Please enter the interest rate(e.g., nine percet should be entered as 9.0)." << endl;
cin >> interestRate;
newAmount = FutureValue(amount,interestRate);
cout << "The new dollar amount is" << newAmount << endl;
return 0;
}
void FutureValue(double initialAmount, double interestRate)
{
//Declare variables
double finalAmount;
finalAmount = ( 1 + interestRate/100) * initialAmount;
return(finalAmount);
}
The first error was indicated to be on line 42, where newAmount is. The second one is on line 57, where return(FinalAmount) is.
Any help regarding this issue is very welcome!
The following line in FutureValue is not right since the return type of the function is void.
return(finalAmount);
Also, the line
newAmount = FutureValue(amount,interestRate);
in main is not right due to the same reason -- the return type of the function is void.
Change the return type of the function to double.
double FutureValue(double initialAmount, double interestRate)
{
//Declare variables
double finalAmount;
finalAmount = ( 1 + interestRate/100) * initialAmount;
return(finalAmount);
}
It can be simplified to:
double FutureValue(double initialAmount, double interestRate)
{
return ( 1 + interestRate/100) * initialAmount;
}

c++ class passing member function issues

In class were learning about classes and structures, Im working on a program that is supposed to have to member functions in the class, one doing calculations and one to return certain values, it seems Im running into trouble calling the functions maybe? IM not a 100% sure because c++ cant specify the error. I hope you can help me, thank you in advance.
#include <iostream>
#include <cstdlib>
using namespace std;
void rocket(double massR,double massE, double massP,double avgTh,double bd);
double rocketreturn(double& MV,double& MA);
class Rocket
{
private:
double massR;
double massE;
double massP;
double avgTh; // average thrust
double bd; //burn duration
public:
void rocket(double massR,double massE, double massP,double avgTh,double bd)
{
massR=massR/1000;
massE=massE/1000;
massP=massP/1000;
double LM=massR+massE;
double MCP=massR+massE-massP;
double AM=(LM+MCP)/2;
double acc=(avgTh/AM)-9.8;
double MV= acc * bd;
double Alt=.5*acc*.5*.5;
double t=MV/9.8;
double MA=Alt+MV*t+.5*-9.8*t*t;
}
double rocketreturn(double& MV, double& MA)
{
cout<< MV;
cout<< MA;
}
};
int main( )
{
double massR; // mass of the rocket
double massE; // mass of the engine
double massP; // mass of the propellant
double avgTh; // average thrust
double bd; // burn duration
double MV; // max velocity
double MA; // max altitude
char ans;
system("CLS");
cout << "Take Home # by - "
<< "Rocket Object\n\n";
do
{
cout <<"Enter the mass of the rocket: "<<endl;
cin >> massR;
cout <<"Enter the mass of the engine: "<<endl;
cin >> massE;
cout <<"Enter the mass of the propellant: "<<endl;
cin >> massP;
cout <<"Enter the average thrust of the engine: "<<endl;
cin >> avgTh;
cout <<"Enter the burn duration of the engine: "<<endl;
cin >> bd;
rocketreturn(MV,MA);
cout <<"the rockets maximum velocity is " << MV<<endl;
cout <<"the rockets maximum altitude is "<<MA<<endl;
cout <<"Would you like to run the program again (Y or N)?"<<endl;
cin>>ans;
}
while(ans=='y'||ans=='Y');
}
You can try using the following program structure and fill in the details the way you wish. Note, it won't compile.
#include <iostream>
using namespace std;
class Rocket {
private:
double mR, mE;
public:
/* Constructor. It is missing in your program. You probably want it */
Rocket(double massR, double massE) {
/* Better to use initialization list, but this should work too */
mR = massR;
mE = massE;
}
double rocketreturn(double & a, double & b) {
/* Do sth with the parameters. But return a double,
which you are not doing in your program */
double result = a + b;
return result;
}
};
int main() {
double x, y;
do {
cin >> x >> y;
Rocket my_rocket(x, y);
double z = my_rocket.rocketreturn(x, y); // Assignment not necessary
} while ( /* some condition */) //my_rocket object will be destroyed after scope goes out
return 0;
}

C++ object oriented problems [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
This is an assignment i am trying to figure out:
Create a new project named Project3 and create a class named Rover
Within the Rover class, specify the following member instance variables:
name(string)
x position on a grid (integer)
y position on a grid (integer)
direction by compass – N, S, E, or W (String)
speed (0 – 5 meters per second, integer)
Within the Rover class, specify the following methods:
Default constructor – set the rover’s position to (0,0), its speed to 0, its direction to
North.
Constructor that receives parameters to initialize all five instance variables described above
Setter methods for each instance variable
Getter methods for each instance variable
getRoverData – returns a string that displays values for each instance variable of the
current rover object, placing each value on a separate line, as follows:
Rover name: A
X-position: 0
Y-position: 0
Direction: E
Speed: 1
Create a class client (main) that creates an array of the a maximum of five rovers and gets the initial
values for all rovers from the user. After the user specifies values for each rover, display a summary
of the rover’s values as shown above.
I have about a billion errors and i dont know why.
using namespace std;
class Rover {
private:
string name;
int x;
int y;
string direction;
int speed;
int position[10][10];
public:
void Rover();
void constructor(string name, int x, int y, string direction, int speed);
void setName(string name);
void setX(int x);
void setY(int y);
void setDirection(string direction);
void setSpeed();
string getName();
int getX();
int getY();
string getDirection();
int getSpeed();
string getRoverData();
};
void Rover::Rover() {
r1.position[0][0];
r1.speed = 0;
r1.direction = "N";
}
string Rover::getRoverData() {
cout << "Rover name: " << r1.getName() << endl;
cout << "X-position: " << r1.getX() << endl;
cout << "Y-position: " << r1.getY() << endl;
cout << "Direction: " << r1.getDirection() << endl;
cout << "Speed: " << r1.getSpeed() << endl;
}
void Rover::constructor(string name1, int x1, int y1, string direction1, int speed1) {
r1.name = name1;
r1.x = x1;
r1.y = y1;
r1.direction = direction1;
r1.speed = speed1;
}
void Rover::setName(string name) {
r1.name = name;
}
void Rover::setX(int x) {
r1.x = x;
}
void Rover::setY(int y) {
r1.y = y;
}
void Rover::setDirection(string direction) {
r1.direction = direction;
}
void Rover::setSpeed(int speed) {
r1.speed = speed;
}
string Rover::getName() {
return name;
}
int Rover::getX() {
return x;
}
int Rover::getY() {
return y;
}
string Rover::getDirection() {
return direction;
}
int Rover::getSpeed() {
return speed;
}
int main(int argc, char** argv) {
string name;
int x;
int y;
string direction;
int speed;
Rover r1;
r1.constructor("Yoda", 3, 3, "N", 3);
cout << "Enter name for Rover: ";
cin >> name;
r1.setName(name);
cout << "Enter its x position: ";
cin >> x;
r1.setX(x);
cout << "Enter its y position: ";
cin >> y;
r1.setY(y);
cout << "Enter direction N,E,S,W: ";
cin >> direction;
r1.setDirection(direction);
cout << "Enter its speed: ";
cin >> speed;
r1.setSpeed(speed);
r1.getRoverData();
return 0;
}
Your example appears incomplete. I'm guessing you just missed including the following lines in your post
#include <string>
#include <iostream>
using namespace std;
First, constructors do not have a return type so void Rover(); makes no sense. Remove void and you're golden there.
Second, what exactly do you think r1 is supposed to be? The compiler should tell you the identifier is undefined because it isn't. remove r1. from your member functions (i.e. anything function starting with Rover::. and you're golden there.
Third, what do you think r1.position[0][0] is going to do? It's just an expression that does nothing. Even position[0][0] is not going to do anything. Perhaps you want to initialize the array somehow but you haven't provided enough information to determine what you're trying to accomplish with it.
Fourth, the member function void Rover::setSpeed(int) has not been declared within the Rover class. Did you forget something? Based on your code it should be
int Rover::getSpeed()
{
return speed;
}
Fifth, void Rover::setSpeed(); doesn't make much sense unless it actually accepts an argument.