enter image description here
this has all the detail of the question
how do we print the number of options
we use this formula options = (cargo / lorrysize) + 1 this gives us the numbers of options
but after that we are stuck
example cargo size is 100
100 100/30=3+1=4
option 1
30
30
30
option 2
30
30
10
10
10
option 3
10x10
option 4
30
10x7
second example
150 150/30=5+1=6
option 1
30x5
option 2
30x4
10x3
option 3
30x3
10x6
option 4
30x2
10x9
option 5
30
10x12
option 6
10x15
we trying to do that but have no idea how to code that the "for loop" part
I hope this is enough for you guys to understand
#include <iostream>
#include <vector>
#include <iterator>
#include <fstream>
#include<string>
using namespace std;
/*
Steps to complete program
Step 1: Find total options available (how many Lorrys & Vans) for the input cargo capacity in .txt files
Step 2: For each option, find its: Amount of Lorrys and Vans
Total cost for both the Lorrys and Vans
Find the max trip
Step 3: Find the top 3 cheapest/lowest cost trips and display
Step 4: Find the fastest available trip and display
*/
class CTS //cargo transport system
{
int i;
int cargo, lorryprice, vanprice, lorrysize, vansize, allOps;
//vector<double> options, lorry, vans, totalC, nooftrips;
//vector <double>::iterator option, minilorry, cost, trips, van;
public:
void set_cargo(int);
void set_lorryprice(int);
void set_vanprice(int);
void set_lorrysize(int);
void set_vansize(int);
};
void CTS::set_cargo(int total_cargo){
cargo = total_cargo;
}
void CTS::set_lorryprice(int lorryP){
lorryprice = lorryP;
}
void CTS::set_vanprice(int vanP){
vanprice = vanP;
}
void CTS::set_lorrysize(int lorryS){
lorrysize = lorryS;
}
void CTS::set_vansize(int vanS)
{
vansize = vanS;
}
int main()
{
int cargo, lorryprice, vanprice, lorrysize, vansize, options, i;
ifstream infile;
infile.open("size.txt");
if(infile.is_open()){
infile >> cargo;
infile >> lorryprice;
infile >> vanprice;
infile >> lorrysize;
infile >> vansize;
}
CTS run;
run.set_cargo(cargo);
run.set_lorryprice(lorryprice);
run.set_vanprice(vanprice);
run.set_lorrysize(lorrysize);
run.set_vansize(vansize);
infile.close();
options = (cargo / lorrysize) + 1;
for (i = 0; i < options; i++)
{
cout << i << " " << cargo - lorrysize << endl; // this part we need help with we have no clue
}
/*cout << cargo << endl;
cout << lorryprice << endl;
cout << vanprice << endl;
cout << lorrysize << endl;
cout << vansize << endl;*/
return 0;
}
Once you have the maximum number of lorries, you can subtract the lorries' cargo and calculate the number of vans remaining like so:
for (int num_lorries = 0; num_lorries < options; num_lorries++) {
int remaining_cargo = cargo - lorrysize * num_lorries;
int num_vans = remaining_cargo / vansize;
// Exercise for you: figure out why this bit is needed.
// (consider remaining_cargo=25 and vansize = 10)
if (remaining_cargo % vansize > 0) {
num_vans++;
}
Solution sol(num_lorries, num_vans);
// Do something with sol
}
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 15 days ago.
Improve this question
Here is my program, it is using c++ and I done it on MacOS VSCode.
Library:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <string>
#include <iomanip>
using namespace std;
Function:
float* read_data(int& size){
int a_size = 0;
static float a[10];
float* temp = a;
cout << "Please enter values, and press 'Q' when finished: ";
for (int i = 0; i < size; i++){
cin >> a[i];
if (cin.fail()){
break;
}else{
a_size++;
}
}
cin.clear();
size = a_size;
return temp;
}
Main function:
int main(){
int size1 = 10;
int size2 = 10;
int size3 = 0;
float array[10];
float addarray[10];
float longarray[20];
float* ptr = array;
float* addptr = addarray;
float* longptr = longarray;
cout << fixed << setprecision(2);
ptr = read_data(size1);
cout << setw(15) << "Original array" << setw(5) << "=" << setw(5) << "{ " << *ptr;
for (int i = 0; i < size1; i++){
cout << ", " << *(ptr + i);
}
cout << " }" << endl;
for (int i = 0; i < size1; i++){
*(longptr + size3) = *(ptr + i);
size3++;
}
addptr = read_data(size2);
for (int i = 0; i < size2; i++){
*(longptr + size3) = *(addptr + i);
size3++;
}
cout << setw(15) << "New array" << setw(5) << "=" << setw(5) << "{ " << *longptr;
for (int i = 0; i < size3; i++){
cout << ", " << *(longptr + i);
}
cout << " }" << endl;
return 0;
}
The main objective of the program was to prompt the user for an array, maximum of 10 elements. Prompting the user was done using the float* read_data(int& size) function.
The program would echo or print out the inputted array.
After that, the user was prompt for a second time using the same function to get another array of elements, in this case is a list of float values.
Then, the program would use a dynamic data allocation (DMA) technique to combine the two array into one long array. The new array will be printed out and the program is terminated.
Problem
As I said before, the program are supposed to prompt the user for inputs every time the read_data() were called.
I called the function twice. It did run twice, but failed to prompt the user for input the second time around.
I thought the problem was due to the cin.fail() arguments. That is why I tried to mess with the cin.ignore() and cin.clear() either by removing them or only using one of them.
I am honestly at lost on what is the root of the problem.
The heart of the issue is that you want users to enter 'Q', a char, into your float variable.
Here's a small example:
#include <iostream>
int main() {
int a;
std::cin >> a;
if (std::cin.fail()) {
std::cout << "Fail.\n";
} else {
std::cout << "All clear.\n";
}
std::cin >> a;
std::cout << (2 * a) << '\n';
}
Output:
~/tmp
❯ ./a.out
Q
Fail.
0
~/tmp
❯ ./a.out
3
All clear.
3
6
So, you can see that you were on the right track. The issue is that if std::cin did fail, you are now responsible to clean up your mess.
std::cin.clear() is a good start. It resets the fail flag bits. But the stream is still in a bad state. What you haven't done is clean it up completely.
You're calling std::cin.ignore(), but leaving the parameter list empty.
Something like this is best practice:
#include <iostream>
#include <limits>
int main() {
int a;
std::cin >> a;
if (std::cin.fail()) {
std::cout << "Fail.\n";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.clear();
} else {
std::cout << "All clear.\n";
}
std::cin >> a;
std::cout << (2 * a) << '\n';
}
Output:
~/tmp
❯ ./a.out
Q
Fail.
3
6
While that should fix address the question, your code is still fundamentally broken.
EDIT
Here's a mini-code review:
#include <iostream>
#include <algorithm> // These includes
#include <cmath> // are
#include <cstdlib> // not
#include <string> // used
#include <iomanip>
using namespace std; // Bad practice
// You should not attempt to return a C-style array
float* read_data(int& size){ // Why is the size being passed by reference?
int a_size = 0;
static float a[10]; // Not doing what you think
float* temp = a;
cout << "Please enter values, and press 'Q' when finished: ";
for (int i = 0; i < size; i++){ // Formatting; should be ") {"
cin >> a[i];
if (cin.fail()){ // Addressed above; root cause of your question
break;
}else{
a_size++;
}
}
cin.clear();
size = a_size;
return temp;
}
// While I assume the goal of the assignment is to get familiar with pointers,
// This assignment is trivial with vectors.
int main(){
int size1 = 10; // If declared const/constexpr, you'd only need one **
int size2 = 10; // These are bad names
int size3 = 0; // Front loading declarations is bad practice.
float array[10]; // ** And could use that variable here to avoid the magic number
float addarray[10];
float longarray[20]; // Not dynamic per your requirements.
float* ptr = array; // Still not dynamic, also unnecessary given the prior declarations
float* addptr = addarray;
float* longptr = longarray;
cout << fixed << setprecision(2);
ptr = read_data(size1);
// The first cout is not good, what do you think *ptr will print?
cout << setw(15) << "Original array" << setw(5) << "=" << setw(5) << "{ " << *ptr;
for (int i = 0; i < size1; i++){
cout << ", " << *(ptr + i); // The pointers can still use array syntax
}
cout << " }" << endl;
for (int i = 0; i < size1; i++){
*(longptr + size3) = *(ptr + i);
size3++;
}
addptr = read_data(size2);
for (int i = 0; i < size2; i++){
*(longptr + size3) = *(addptr + i);
size3++;
}
// As soon as you start repeating yourself, consider writing a function.
// The logic will only live in one place, and only need to be changed in
// one place.
cout << setw(15) << "New array" << setw(5) << "=" << setw(5) << "{ " << *longptr;
for (int i = 0; i < size3; i++){
cout << ", " << *(longptr + i);
}
cout << " }" << endl;
return 0;
}
A lot going on that is less than great. The biggest flub appears to be the static array. static in this scenario extends the lifetime of the variable until the end of the program. So, when you call this function the second time, you overwrite the first array with the second because there's only ever one array for every call of that function. In the future, I would refrain from grabbing random code online and just dumping it in your program unless you know what it does.
Now, let's move on to a working solution.
The first thing I'm going to do is state the requirements as I understood them.
Have the user enter data to fill two arrays of floats.
Each array should hold a maximum of ten elements.
The user enters "Q" to indicate that they are finished entering data.
Print the first array.
Tack the second array on to the end of the first, in a dynamic fashion.
Print the combined array.
Anytime you get an assignment, your first task should be to restate the problem in your own words. This will clarify requirements and you will demonstrate to yourself that you understand the problem to be solved.
What makes this interesting is the "Q" to quit. Note that I'm using double quotes. We will read all of our data as strings, and we have to convert to float as needed.
std::stof() exists, but it's not as simple as just calling it. That function can throw exceptions, and we want to ensure that only actual float values get converted.
So we'll wrap that call in a function of our own. Here's an example:
#include <exception>
#include <iostream>
#include <string>
class bad_user_input : public std::exception {
const char* what() const noexcept override {
return "User input was not valid.";
}
};
float convert_string_to_float(const std::string& val) {
std::size_t marker = 0;
float f = 0.0f;
try {
f = std::stof(val, &marker);
} catch(...) {
throw bad_user_input();
}
// Was the entire value entered a float?
if (marker != val.length()) {
throw bad_user_input();
}
// Getting here means a valid float was entered.
return f;
}
int main() {
float f = 0.0f;
// Test the function
try {
f = convert_string_to_float("5.6");
} catch(...) {
std::cerr << "Issue.\n";
}
std::cout << f << "\n\n";
f = 0.0f;
try {
f = convert_string_to_float("5.6cat");
} catch(...) {
std::cerr << "Issue.\n";
}
std::cout << f << "\n\n";
f = 0.0f;
try {
f = convert_string_to_float("Q");
} catch(...) {
std::cerr << "Issue.\n";
}
std::cout << f << '\n';
}
Output:
❯ ./a.out
5.6
Issue.
0
In convert_string_to_float
stof: no conversion
Issue.
0
Now that we can convert strings to floats, with guarantees, we are ready to read values. To test that we're reading correctly, we also want to be able to print our arrays:
#include <exception>
#include <iostream>
#include <string>
class bad_user_input : public std::exception {
const char* what() const noexcept override {
return "User input was not valid.";
}
};
float convert_string_to_float(const std::string& val) {
std::size_t marker = 0;
float f = 0.0f;
try {
f = std::stof(val, &marker);
} catch(...) {
throw bad_user_input();
}
// Was the entire value entered a float?
if (marker != val.length()) {
throw bad_user_input();
}
// Getting here means a valid float was entered.
return f;
}
void read_array_from_user(float* arr, int& size, const int maxCapacity, std::istream& sin = std::cin) {
size = 0;
std::string input;
while (size < maxCapacity && std::getline(sin, input)) {
if (input == "Q" || input == "q" || input.length() == 0) {
return;
}
try {
arr[size] = convert_string_to_float(input);
} catch(const std::exception& e) {
std::cerr << "Bad input. Reason: " << e.what() << "\nTry again.\n";
continue;
}
++size;
}
}
void print_array(float* arr, int size, std::ostream& sout = std::cout) {
sout << "{ ";
for (int i = 0; i < size; ++i) {
sout << arr[i] << (i == size - 1 ? " " : ", ");
}
sout << "}\n";
}
int main() {
constexpr int maxArrayCapacity = 10;
float arrayOne[maxArrayCapacity];
int arrayOneSize = 0;
read_array_from_user(arrayOne, arrayOneSize, maxArrayCapacity);
print_array(arrayOne, arrayOneSize);
}
Output:
~/tmp
❯ ./a.out
1
2
3
4
q
{ 1, 2, 3, 4 }
~/tmp took 3s
❯ ./a.out
1
2
Q
{ 1, 2 }
~/tmp took 2s
❯ ./a.out
1
2
3
4
5
6
{ 1, 2, 3, 4, 5, 6 }
~/tmp took 4s
❯ ./a.out
1
2
3
4
5
6
7
8
9
0
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }
~/tmp took 5s
❯ compilecpp tmp_repair.cpp
~/tmp
❯ ./a.out
1
2
3
4
5
6
7
8
9
0
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }
~/tmp took 4s
❯ ./a.out
1
2
3
q
{ 1, 2, 3 }
~/tmp took 2s
❯ ./a.out
1
2b
Bad input. Reason: User input was not valid.
Try again.
2
3
Q
{ 1, 2, 3 }
~/tmp took 3s
❯ ./a.out
1
2
3
Q
{ 1, 2, 3 }
~/tmp took 2s
❯ ./a.out
1
2
3
{ 1, 2, 3 }
So, we can read an array with a maximum of 10 values. The reading is robust enough to handle typos or obviously bad input. But we don't have to read 10 values, it's the maximum. We keep track of the actual size ourselves.
Take note on how simple the main() function is because we put our sub-tasks into their own functions.
Reading the second array only requires a few lines in our main() now.
int main() {
constexpr int maxArrayCapacity = 10;
float arrayOne[maxArrayCapacity];
int arrayOneSize = 0;
read_array_from_user(arrayOne, arrayOneSize, maxArrayCapacity);
print_array(arrayOne, arrayOneSize);
float arrayTwo[maxArrayCapacity];
int arrayTwoSize = 0;
read_array_from_user(arrayTwo, arrayTwoSize, maxArrayCapacity);
print_array(arrayTwo, arrayOneSize);
}
Easy-peasy there. Now we need to combine the arrays "dynamically."
We know the sizes of our two arrays, so we know the size of the final array. Now we just need to allocate the memory on the heap. I'm not going to use new, which is what I assume you're supposed to do. My reasoning is that C++ has had better methods for managing dynamic allocations since 2011.
#include <memory>
// ...
int main() {
constexpr int maxArrayCapacity = 10;
float arrayOne[maxArrayCapacity];
int arrayOneSize = 0;
read_array_from_user(arrayOne, arrayOneSize, maxArrayCapacity);
print_array(arrayOne, arrayOneSize);
float arrayTwo[maxArrayCapacity];
int arrayTwoSize = 0;
read_array_from_user(arrayTwo, arrayTwoSize, maxArrayCapacity);
print_array(arrayTwo, arrayTwoSize);
int combinedArraySize = arrayOneSize + arrayTwoSize;
// This is considered dynamic; it's allocated on the heap
auto combinedArray = std::make_unique<float[]>(combinedArraySize);
int idx = 0;
for (int i = 0; i < arrayOneSize; ++i) {
combinedArray[idx] = arrayOne[i];
++idx;
}
for (int i = 0; i < arrayTwoSize; ++i) {
combinedArray[idx] = arrayTwo[i];
++idx;
}
print_array(combinedArray.get(), combinedArraySize);
}
Output:
~/tmp
❯ ./a.out
1
2
q
{ 1, 2 }
3
4
5
q
{ 3, 4, 5 }
{ 1, 2, 3, 4, 5 }
Hopefully, the most gnarly stuff is over where you get the user input, mostly due to the requirement that users can enter a letter to signal they're done. And that makes sense since now you have to do type conversions. Other languages like python make it possible with a lot less LOC (Lines Of Code) on your part. The task itself is not difficult, but ensuring users behave is a whole other beast. If you're allowed to assume well-behaved input will always be provided, you can simplify the code quite a bit.
This a problem from introduction to C++ course. We need to read a Data from the file jan91.dat. Data looks like that.
1 59 26 43 .. .. .. .. ..
2 40 12 24 .. .. .. .. ..
3 21 14 18 .. .. .. .. ..
4 .. .. .. .. .. .. .. ..
First number is a date, we want to read only second and third number from each line.
Second number is Max Temperature, and third number is Min Temperature. Later we may need to read other numbers in a line like humidity etc that (but it is not required yet).
// This program determines the number of days in each of six
// temperature categories for the days of January 1991.
#include <iostream> // required for cin and cout
#include <iomanip> // required for set precision, setw
#include <fstream> // required for ifstream and ofstream
#include <string> // required for string
using namespace std; // standard library
int main()
{
// Name of Variables
int i, below0 = 0, from0to32 = 0, from33to75 = 0, above75 = 0;
double min_temp, max_temp, date = 0;
const string FILENAME = "jan91.dat";
// Open input file
ifstream jan91;
jan91.open(FILENAME.c_str());
if (jan91.fail()) {
cerr << "Error opening file" << endl;
exit(1);
}
// Read and check temperature per day
while (!jan91.eof()) {
(jan91 >> date >> max_temp >> min_temp);
if (min_temp < 0);
below0++;
if (max_temp > 75) {
from0to32++;
from33to75++;
above75++;
}
else if (max_temp > 33 && max_temp < 75) {
from0to32++;
from33to75++;
}
else if (max_temp > 0 && max_temp < 33) {
from0to32++;
}
}
// Print results
cout << "January of 1991" << endl;
cout << "Temperature Ranges \t Number of Days " << endl;
cout << "Below 0 \t \t\t" << below0 << endl;
cout << "0 to 32 \t \t\t" << from0to32 << endl;
cout << "33 to 75\t \t\t" << from33to75 << endl;
cout << "Above 75 \t \t\t" << above75 << endl;
// Close file
jan91.close();
// Exit program.
return 0;
}
some people suggested to use "getline" but for some reason I could not use it in my Visual Studio 17.3.3
Please advise
I am extremely confused. I have to follow these specific guidelines:
Make a program that will compute and output the average of 10 exam scores, entered by the user. Finish the function, so that the main will work correctly. Feel free to modify the main as you please as well.
I do not believe we need to change the main and do not believe we should use 10 variables. Here is the code I must add to, I believe the main is finished. Your help is very appreciated!!!!
#include <iostream>
using namespace std;
NOT ADD CODE HERE!!!
float calculateAverageTestScore(int amountOfScores);
int main(void)
{
const int NUMBER_OF_SCORES = 10;
cout << "The average test score was: " << calculateAverageTestScore(NUMBER_OF_SCORES) << endl;
return 0;
}
//INPUT: an amount of test scores
//OUTPUT: the average of these scores
//This function will obtain amountOfScores test scores from the user, and return
//their average - to be used elsewhere.
float calculateAverageTestScore(int amountOfScores)
{
float average;
//add code here
return average;
}
Should do the trick.
#include <iostream>
#include <string>
float calculateAverageTestScore(int amountOfScores);
int main() {
const int NUMBER_OF_SCORES = 10;
const float score = calculateAverageTestScore(NUMBER_OF_SCORES);
std::cout << "The average test score was: " << score << '\n';
}
float calculateAverageTestScore(int amountOfScores) {
float sum = 0;
std::string buffer;
for (int i = 0; i < amountOfScores; ++i) {
std::cout << "score #" << i + 1 << ": ";
std::getline(std::cin, buffer);
sum += std::stof(buffer); // TODO: Error handling
}
return sum / amountOfScores;
}
So I am trying to make a rental program that reads in a file with a list of cars ( year, make, model, price, and if available).
I also have to make options such as showing all cars and having the user look at a specific car( for example they type 1, and it will show the top car on the text file). This is where I am confused, I tried making several cars such as car1,car2, etc. But I am having trouble registering the first read car into car1.
This is an example file.
CarData.txt
2014 Toyota Tacoma 115.12 1
2012 Honda CRV 85.10 0
2015 Ford Fusion 90.89 0
2013 GMC Yukon 110.43 0
2009 Dodge Neon 45.25 1
2011 Toyota Rav4 65.02 1
2012 Mazda CX5 86.75 1
2016 Subaru Outback 71.27 0
2015 Ford F150 112.83 1
2010 Toyota Corolla 50.36 1
Source code:
#include <iostream>
#include <fstream>
using namespace std;
struct car
{
int year;
char make[10];
char model[10];
float price;
int available;
}car1[1], car2[1], car3[1], car4[1], car5[1], car6[1], car7[1], car8[1], car9[1], car10[1];
void copy_string(char d[][50], char s[][50]);
int my_strcmp(char *a, char *b);
// Main Function
int main ()
{
// declare variables
int choice;
car carLib[10];
char array[30][50];
char filename[10];
ifstream carInData;
//prompt user for input file
cout << " Enter file name: ";
cin >> filename;
cout << " 1 - Show Cars\n";
cout << " 2 - Rental Cost\n";
cout << " 3 - Most Expensive Car\n";
carInData.open(filename);
cin >> choice;
if(carInData.is_open());
{
int count = 0;
// read list of names into array
for( count; count < 1; count++){
carInData >> car1[count].year >> car1[count].make >> car1[count].model >> car1[count].price >> car1[count].available;
carInData >> car2[count].year >> car2[count].make >> car2[count].model >> car2[count].price >> car2[count].available;
switch (choice){
case 1:
cout << car1[count].year << " " << car1[count].make << " " << car1[count].model << " " << car1[count].price << " " << car1[count].available << " " << "\n";
cout << car2[count].year << " " << car2[count].make << " " << car2[count].model << " " << car2[count].price << " " << car2[count].available << " " << "\n";
break;
}
}
}
return 0;
}
// copy function
void copy_string(char d[], char s[]) {
int c = 0;
while (s[c] != '\0') {
d[c] = s[c];
c++;
}
d[c] = '\0';
}
// string copy
int my_strcmp(char *a, char *b)
{
while (*a && *b && *a == *b) { ++a; ++b; }
return *a - *b;
}
Here is example source, how to work with array of struct type, like car carLib[300];:
#include <iostream>
struct car
{
int year;
char make[10];
char model[10]; // that's only 9 letters for zero-terminated strings
float price;
int available;
};
int main()
{
constexpr size_t maxCarLib = 300;
car carLib[maxCarLib]; // array of memory reserved for several cars
size_t carLibCount = 0; // current allocation of array (zero cars entered)
carLib[carLibCount++] = car {1993, {"Nohda"}, {"XYZ"}, 123.45, 0};
carLib[carLibCount++] = car {1994, {"Frod"}, {"Peon"}, 543.21, 1};
carLib[carLibCount++] = car {1977, {"Nohda"}, {"ABC"}, 3.32, 0};
std::cout << "Cars in library: " << carLibCount << std::endl;
for (size_t carIndex = 0; carIndex < carLibCount; ++carIndex) {
const car & carI = carLib[carIndex];
printf("Car at index %lu: %d %s %s %f %d\n",
carIndex, carI.year, carI.make, carI.model, carI.price, carI.available);
}
// Find most expensive car
float mostExpensivePrice = 0; // most expensive price found
size_t mostExpensiveIndex = carLibCount; // index points beyond array ("no car")
for (size_t carIndex = 0; carIndex < carLibCount; ++carIndex) {
if (carLib[carIndex].price <= mostExpensivePrice) continue;
// the car at carIndex is more expensive than old maximum, remember it
mostExpensivePrice = carLib[carIndex].price;
mostExpensiveIndex = carIndex;
}
if (mostExpensiveIndex == carLibCount) {
std::cout << "Most expensive car not found." << std::endl;
} else {
const car & carI = carLib[mostExpensiveIndex];
printf("Most expensive car at index %lu: %d %s %s %f %d\n",
mostExpensiveIndex, carI.year, carI.make, carI.model, carI.price, carI.available);
}
}
Live demo
Mind you, this is just array indexing example, this "old C" code style is very error prone to index-out-of-bounds code, overwriting memory, or accessing wrong memory. That's why in modern C++ you can use std::vector<car> carLib; instead, which is much better fit for such task.
Vector example:
#include <iostream>
#include <vector>
struct car
{
int year;
char make[10];
char model[10]; // that's only 9 letters for zero-terminated strings
float price;
int available;
};
int main()
{
std::vector<car> carLib;
carLib.push_back(car {1993, {"Nohda"}, {"XYZ"}, 123.45, 0});
carLib.push_back(car {1994, {"Frod"}, {"Peon"}, 543.21, 1});
carLib.push_back(car {1977, {"Nohda"}, {"ABC"}, 3.32, 0});
std::cout << "Cars in library: " << carLib.size() << std::endl;
for (const auto & kar : carLib) {
printf("%d %s %s %f %d\n",
kar.year, kar.make, kar.model, kar.price, kar.available);
}
if (0 < carLib.size()) {
// indexing trough size_t index still possible with vector
std::cout << "Last car price is: " <<
carLib[carLib.size()-1].price << std::endl;
// Last valid index being size()-1, because first index is 0
}
}
But that C-like is good for you to study details about computer memory, also it does introduce you to the "float is not a good variable type for amounts", as the live demo shows. So open it in debugger, and find some memory window, and study how the data are actually laid out in memory, how 10 letter long name of car makes your struct problematic, etc...
The std::vector stores the struct in the same way as the bare array, only having few more helper data around, and reserving the memory dynamically as you need, so understanding the array example (and it's shortcomings) first is just as important.
I'm having a little trouble with my code. It's pretty much supposed to open two files, and compare the first twenty line of the file "StudentAnswers.txt" [inputted as a char into a char array] against a char value in (each line of another file) "CorrectAnswers.txt" in another array at the same position (index). It's like a linear search, but the same position in the arrays. Then a report should be displayed, detailing which question the student missed, the given answer, the correct answer, and if the student passed (got >= 70%) or not, like the following:
Report for Student X:
2 (A/D), 3 (C/D), 5(D/A)
This student passed the exam!
Then it should clear the SAArray, and feed the next twenty lines from StudentAnswers.txt, and start the process all over again. I guess the program has to determine the number of students from (lines of 'StudentAnswers.txt' file / 20).
I'm having trouble displaying the report, and having the array clear itself after the program. I'm guessing this can be done with a while loop and an accumulator for the number of students (to be determined by above equation).
Also, Visual Studio seems to go to "Missed __ questions for a total of ___ %", and then keep looping -858993460.
Any help would be appreciated.
#include <iostream>
#include <fstream>
#include <string>
#include <array>
#include <algorithm>
using namespace std;
void GradeReturn(char[], char[], int, int, int);
string PassFail(float);
int main()
{
ifstream SA("StudentAnswers.txt");
ifstream CA("CorrectAnswers.txt");char CAArray[20];
char SAArray[20];
// char SA2Array[20];
bool isCorrect;
int correct;
int incorrect;
int counter;
correct = 0;incorrect = 0;
counter = 0;
cout << endl;
if (!SA.fail())
{
cout << "'StudentAnswers.txt' file opened successfully." << endl;
cout << "'CorrectAnswers.txt' file opened successfully." << endl << endl;
int a = 0;
int b = 0;
while (a < 20)
{
CA >> CAArray[a];
a++;
} // while loop to feed char into the array
while (b < 20)
{
SA >> SAArray[b];
b++;
}
} // while loop to feed char into array
CA.close(); // closing "CorrectAnswers.txt"
SA.close(); // closing "StudentAnswers.txt"
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter);
return 0;
}
void GradeReturn(char CAArray[], char SAArray[], int correct, int incorrect, int counter)
{
float percent;
float hundred;
int student;
int catcher[20];
int writeCatcher; int starter;
int catcher_size;
student = 0;
writeCatcher = 0;
catcher_size = ((sizeof catcher) / 4);
while (counter < 20)
{
if ((CAArray[counter]) == (SAArray[counter]))
{
correct++;
cout << "Good job!" << endl;
} // correct handling
else
{
incorrect++;
cout << "You got question " << counter << " wrong." << endl;
counter >> catcher[writeCatcher];
writeCatcher++;
} // incorrect handling
counter++;
} // while loop to determine if a student got a question right or wrong
static_cast <float> (incorrect); // float conversion
cout << endl; // for cleanliness
percent = ((static_cast <float> (correct)) / 20); // percentage
hundred = percent * 100;
PassFail(percent);
if (PassFail(percent) == "pass")
{
student++;
cout << "Report for Student " << student << ":" << endl;
cout << "-----------------------------" << endl;
cout << "Missed " << incorrect << " questions out of 20 for ";
cout << hundred << " % correct." << endl << endl;
starter = 0;
while (starter < (sizeof catcher)
{
if(1=1)
{
catcher_size
}
else
{
cout << "";
starter++;
}
}
}
else if (PassFail(percent) == "fail")
{
student++;
cout << "Missed " << incorrect << " questions out of 20 for ";
cout << hundred << " % correct." << endl << endl;
while (starter < catcher_size)
{
if ((catcher[starter]) == -858993460)
{
starter++;
}
else
{
cout << "";
starter++;
}
}
}
return;
}
string PassFail(float percent)
{
if (percent >= 0.70) // if <pass>
{
return "pass";
}
else // if <fail>
{
return "fail";
}
cout << endl;
}
To get a loop you should keep streams open instead of closing them after reading 20 lines.
As pseudo code that would be:
a = 0;
while(streams_not_empty)
{
CA >> CAArray[a];
SA >> SAArray[a];
++a;
if (a == 20)
{
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter);
a = 0; // Reset a
}
}
CA.close(); // closing "CorrectAnswers.txt"
SA.close(); // closing "StudentAnswers.txt"
You would also need to pass correct, incorrect, counter by reference so that the GradeReturn can change their value and their by do the accumulation.
Like:
void GradeReturn(char CAArray[], char SAArray[], int& correct, int& incorrect, int& counter)
Further you shouldn't rely on being able to read exactly Nx20 lines from the files every time. A file could have, e.g. 108 (5x20 + 8) lines, so you code should be able to handle the with only 8 lines. In other words, don't hard code 20 in your function like while (counter < 20). Instead pass the number of lines to be handled and do while (counter < number_to_handle).
Something like this as pseudo code:
a = 0;
while(streams_not_empty)
{
CA >> CAArray[a];
SA >> SAArray[a];
++a;
if (a == 20)
{
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter, a);
// ^
a = 0; // Reset a
}
}
if (a != 0)
{
// Process the rest
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter, a);
}
CA.close(); // closing "CorrectAnswers.txt"
SA.close(); // closing "StudentAnswers.txt"
One problem you have is you're trying to compare C-style strings with the == operator. This will compare them essentially as if they were pointers to char, i.e. compare whether they point at the same location in memory, not compare the contents of the string. I urge you to look up array-decay and c-string variables to understand more.
Specifically, if (PassFail(percent) == "pass") isn't going to do what you want it to. strcomp doc, strncmp doc using std::string variables instead of c-style strings would all work, but it would be better simply to compare percent to a value, i.e. if(percent >= 0.70 directly instead of calling PassFail and comparing a string.
There are many other issues here also, you at one point call PassFail but do nothing with the return value. The only side affect of PassFail is cout << endl, if that's what you intend, it's a poor decision and hard to read way to put a newline on the console.
Try asking your compiler for more warnings, that's often helpful in finding these types of issues. -Wall -Wextra work for gcc, you may have to read your compiler manual...