How to write functions and call them from main [closed] - c++

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 7 years ago.
Improve this question
#include<iostream>
#include<iomanip>
#include<string>
#include<fstream>
using namespace std;
struct studentType
{
string studentFName[20];
string studentLName[20];
string studentData[20][3];
int testscore[20][5];
char grade[20];
};
studentType s;
int main()
{
int index;
int maxindex;
int maxindex1;
int coldex;
int coldex1;
int totalscore[20];
double avscore[20];
double highscore;
double highindivscore;
maxindex = 0;
maxindex1 = 0;
coldex1 = 0;
ifstream infile;
infile.open("test.txt");
for(index = 0; index < 20; index++)
{
infile >> s.studentFName[index] >> s.studentLName[index] >> s.testscore[index][0] >> s.testscore[index][1] >> s.testscore[index][2] >> s.testscore[index][3] >> s.testscore[index][4];
totalscore[index] = ((s.testscore[index][0]) + (s.testscore[index][1]) + (s.testscore[index][2]) + (s.testscore[index][3]) + (s.testscore[index][4]));
avscore[index] = (static_cast<double>(totalscore[index])/5);
if(avscore[index]<= 100)
{
s.grade[index] = 'A';
}
if(avscore[index]<= 89.9)
{
s.grade[index] = 'B';
}
if(avscore[index]<= 79.9)
{
s.grade[index] = 'C';
}
if(avscore[index] <= 69.9)
{
s.grade[index] = 'D';
}
if(avscore[index] <= 59.9)
{
s.grade[index] = 'F';
}
}
for (index = 0; index < 20; index++)
{
cout << s.studentLName[index] << "," << " " << s.studentFName[index] << " " << s.testscore[index][0] << " " << s.testscore[index][1] << " " << s.testscore[index][2] << " " << s.testscore[index][3] << " " << s.testscore[index][4] << " " << s.grade[index] << endl;
}
cout << endl;
for (index = 1; index < 20; index++)
for (coldex = 0; coldex < 5; coldex++)
{
if (s.testscore[maxindex1][coldex1] < s.testscore[index][coldex])
{
maxindex1 = index;
coldex1 = coldex;
}
}
highindivscore = s.testscore[maxindex1][coldex1];
for (index = 1; index < 20; index++)
{
if (avscore[maxindex] < avscore[index])
{
maxindex = index;
}
}
highscore = avscore[maxindex];
cout << s.studentFName[maxindex] << " " << s.studentLName[maxindex] << " Achieved The Highest Average Test Score Of A: " <<highscore <<endl;
cout << s.studentFName[maxindex1] << " " << s.studentLName[maxindex1] << " " << s.testscore[maxindex1][coldex1] << endl;
infile.close();
system("pause");
return 0;
}
here is the homework question, i know i did it wrong which is why i need help. How do i make main function calls. I am new to this. I have this lab that's got me stumped. The assignment reads (emphasis mine):
Write programs for the following and test to make sure they work. Please follow the book’s guidelines or my style guidelines to write code. Write a program that reads students’ names followed by their test scores from the given input file. The program should output to a file, output.txt, each student’s name followed by the test scores and the relevant grade.. Student data should be stored in a struct variable of type StudentType, which has four components: studentFName and studentLName of type string, testScore of type int and grade of type char. Suppose that the class has 20 students. Use an array of 20 components of type StudentType. Your program must contain at least the following functions:
A function to read the students’ data into an array.
A function to assign the relevant grade to each student.
Your program should output each student’s name in this form: last name followed by a comma, followed by a space, followed by the first name; the name must be left justified. Moreover, other than declaring the variables and opening the input and output files, the function main should only be a collection of function calls.

This is called refactoring. I guess for the assignment you want to move everything that is in main into individual functions. You could just cut and paste the whole body of main and move it to one function and call it in main. I don't really think that is the point of the assignment though.
Instead, read over main and separate/extract procedures. You should separate main into functions that do one thing i.e. handle input/output, loop, check some variable and return a letter, etc. These kind of changes not only make the program much easier to understand and come back to later, but also make it much easier to reuse procedures that are repeated throughout the program.

Your code looks fine logically and should work, however, what your homework is asking of you is to essentially code with good style and separate the sections of the program into functions.
Essentially, as an easy fix, just place different sections that do similar things from the code into void functions. For example, this cpp segment:
void function1();
void function2();
void function3();
void main(){
function1();
function2();
function3();
return 0;
}
void function1(){
// Your code. Ex: Some large algorithm.
}
void function2(){
//More code, for a different algorithm. Maybe some input or output.
}
void function3(){
//The final code you want the program to execute.
}
And then pass parameters and adjust return types as needed. It makes the code easier to follow, especially if you have the functions named after what they do such as gradingLogic() or studentOutput().

Related

C++ Need help getting an integer from the user and making sure it is between 2 other integers [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 4 years ago.
Improve this question
I am new to c++ and cant seem to figure out how to simply get an integer from the user and make sure it is between 0-15. Here is my code so far:
When I run the code it only prints Hello world
int main()
{
int greetAndGet();
cout << "Hello";
return 0;
}
int greetAndGet()
{
int i;
cout << "\nPlease give an integer in [1,15]" << endl;
cin >> i;
cout << endl;
}
int greetAndGet(); is a forward declaration of a function, not a call.
Write greetAndGet(); instead.
Note further that a function should be defined/declared before any call to it. So either place the function definition before main, or write
int greetAndGet(); // forward declaration
int main()
{
greetAndGet();
cout << "Hello";
return 0;
}
...
As pointed out in another answer, int greetAndGet() is a forward declaration that you probably intended to be a call; though you do want to forward declare it before main. As for testing the range of the entered value, you could use a loop to check if it is in the range. I think what you want is this:
int greetAndGet();
int main()
{
int num = greetAndGet();
cout << "Hello";
return 0;
}
int greetAndGet()
{
int i;
cout << "\nPlease give an integer in [1,15]" << endl;
do {
cin >> i;
if(i < 1 || i > 15)
{
cout << "Number not in [1,15], please try again" << endl;
}
} while(i < 1 || i > 15);
cout << endl;
return i;
}
I'm not sure what you want to do with the number, but this should get you the entered number.

Bubble sorting in dynamic array of objects in C++

I have class City with following private data: name of city, width,length and height of the city. I have to make dynamic array, which is inserted by constructor by default- City(),when the programs starts.Then the program uses method output() and prints inserted array of cities.
I should use bubble sort to sort the cities by their length. And when this is done, the program should show the sorted cities in increasing lengths.
The problem is that my data are in private(in public everything works excellent but principle of capsulation is violated!) so I can't do bubble sort.
I tried to do another dynamic array of type double double Lengths[n], which content is lengths of first array. Then I do sorting, but program prints only sorted lengths and this is not my goal.
I should print the names of cities sorted by their lengths.
Code:
class City{
private: char *name;
double width;
double length;
double height;
public:void Output();
City();
~City();
double GetLength()
{
return length;
}
double GetWidth(){ return width; }
double GetHeight(){ return height; }
char GetName(){ return *name; }
};
City::City()
{
char ime[20];
cout << "Name= ";
cin >> ime;
name = new char[strlen(ime) + 1];
for (int i = 0; i <=strlen(ime); i++)
name[i] = ime[i];
cout << "Width= ";
cin >> width;
cout << "Length= ";
cin >> length;
cout << "Height= ";
cin >> height;
}
void City::Output()
{
cout << "Name is: " << name << endl;
cout << " Width is: " << width <<" deg"<< endl;;
cout << " Length is: " << length << " deg"<<endl;
cout << " Height is: " << height <<" m"<<endl;
return;
}
City::~City()
{
cout << " " << endl;
cout << "Destructor of City!" << endl;
delete[] name;
}
int main()
{
//City town;
//town.Input();
//town.Output();
int n;
City *mA;
cout << "Input number of cities: " << endl;
cin >> n;
mA = new City[n];
for (int j = 0; j < n; j++)
{
mA[j].Output();
}
cout << "Cities from west to east, sorted by their length" << endl;
double *Lengths = new double[n];
for (int j = 0; j < n; j++)
{
Lengths[j] = mA[j].GetLength();
}
int k = 0;//counter
double max = Lengths[0];
for (int j = 1; j < n; j++)
{
if (Lengths[j - 1] >Lengths[j])
{
max = Lengths[j - 1];
Lengths[j - 1] = Lengths[j];
Lengths[j] = max;
}
}
for (int j = 0; j < n; j++)//cycle for output
{
mA[j].Output();
}
delete[]mA;
return 0;
}
As I can't quite comment on your response, I will give you a few bits of advice. First in the line of:
Array[j]=mA[j].GetName() ;
You have a random space which may be a copy change and relatively minor but for reading purposes that is wrong.
Second your naming conventions are really something you should work on. I should be able to read a variable and understand what it means but instead I struggle to understand what a variable named mA means.
Third your else clause does nothing literally. Your not moving any parts of the array if that is your intention my saying this:
mA[j+1];
you are simply targeting the element in the array that is above the iteration. I see you stuck with your idea of making something similar to a parallel array for the bubble sort, and that is fine but you lack any action in the first loop.
This is not bubble sort what so ever as you are simply going through each iteration and checking if the element in Lengths is equal in length to the element in mA and then storing that element in array but your else statement does nothing.
Your loop should look similar to something like this but I'm gonna get rid of the character array and the extra array for some reason as it is unnecessary and lets say you start out with an array of your objects:
if(myObjects[i].GetLength() > myObjects[i+1].GetLength()) //Shortest to longest name or vice versa?
{
//Store myObject[i] in temp spot
//myObject[i] = myObject[i+1]
//myObject[i+1] = temp Storage
}
This will give you a bubble sort of the objects on the first round. Of course your going to have to find out how to iterate through the array in loop to verify all of the elements have been sorted correctly as this will of course take many iterations for bubble sort.
I don't see a direct question but I can assume majority of the question by your story. You have multiple options on how to solve this case. One of the simple ways to solve this is create a function within the object that allows you to get the length of a member of an object for example in your case it would be name of city.
Create a method inside the object that you can call to return a private method's length. Create a loop that calls this method and checks each element side by side until you can't refine it any longer. Is there a specific reason your using char instead of string for name?
I'm not entirely sure of what you're asking.
However, from what I can tell your main issue is that you can't sort because you're trying to compare two private variables from two objects.
If the objects are placed into an Array of type city, you can bubblesort by length however you would be required to use the getters in order to reference the variables that are private during sorting.
For example (not exact syntax)
if(cityArray[0].getLength() < cityArray[1].getLength())
{
//Do Something
}

How to Pass a String in a function?

I have a function (int, string) in Main:
string word("HELLO");
int x = 0;
char choice;
swap(x, word);
I am trying, with no success, to pass into the following function:
void swap(int, string) {
int x = 0;
string word = "HELLO";
cout << "Would you like to change a letter? Please enter the letter
position. " << endl;
cin >> x;
if (x == 1) {
cout << "What do you want to change it to?" << endl;
cin >> word[0];
I keep getting this error:
Error C2664 'void std::swap(std::exception_ptr &,std::exception_ptr &) throw()': cannot convert argument 1 from 'int' to 'std::exception_ptr &'
What gives?
The main problem with your code is the indentation. Your code is not readable and mostly hard to comprehend it. Beautify it. Write nice, readable and a structured code. You can read more about indentation at the following link.
https://en.wikipedia.org/wiki/Indentation_style
The next thing is the function declaration. You do not declare your function before defining it. The function declaration should be top of the main function and definition of the function should be below the main function.
You can find more info about the function declaration at the following link:
http://en.cppreference.com/w/cpp/language/function
Since you are not using a char array to print out the string, it is useless to go through the string with a loop. Include the <string> library and start to work towards the string type. By passing the string variable inside std::cout is enough to print out the string.
Lastly, since you are trying to manipulate a string variable outside the main function, it is required that you are passing a reference parameter instead.
void myFunction(std::string& parameter);
This way, the original variable that exists inside the main or inside any other function will be altered. Without the reference, &, the value you are trying to modify will not be changed.
The following link demonstrates the use of reference.
http://www.learncpp.com/cpp-tutorial/73-passing-arguments-by-reference/
Please read my comments below of why some changes were applied. I made crafty changes to the change function. You are now eligible to work towards any
string type with any size.
#include <iostream>
#include <string> //When you are working on strings, use the string library.
using namespace std;
//Function declaration is very important. Have the declarations above main.
void change(string&);
int main() {
string word("HELLO");
char choice;
cout << "The word is : " << endl;
cout << word << endl;
//No need for the for loop to print out the string as
// we are working on a string and not a char array.
// for (int i = 0; i < word.length(); i++) {
// cout << word[i];
// }
change(word);
cout << "The new word is" << endl << word << endl;
cout << "Would you like to enter another change ? Enter Y or N ? " << endl;
cin >> choice;
if (choice == 'y' || choice == 'Y') {
change(word);
cout << word << endl;
}
else {
cout << "Good Bye" << endl;
}
system("pause");
return 0;
}
//When your datatype is to be modified outside the function, use the reference
//parameter type '&'.
//Without the reference type, your modified version of the type will only be modified
//inside that function.
//The original one will not be altered.
void change(string& word) {
/*
* size_t is simply unsigned int, to work towards manipulation and accessing
* of string types, use unsigned int or std::size_t
*/
size_t x = 0;
cout << "Would you like to change a letter? Please enter the letter position. " << endl;
cin >> x;
//Check to see if the inputted value is within the string length range.
if(x > 0 && x <= word.length())
cout << "What do you want to change it to?" << endl;
else{
cout << "The entered position is outside the string size range\n";
return; //Quit from the function if the condition is not met.
}
/*
* Instead of using if/else if statements,
* Just make a normal loop. Much simpler.
*/
for(size_t i = 0; i < word.length(); i++){
if((x-1) == i)
cin >> word[i];
}
}

Retrieve all data via void function

Been trying to find a way through this. I am new to C++ and creating a simple program to get the user data, validate and cout to the screen. What i'm trying to do is to have the one function use pointers to get the users input and display back to them. This may have been answered before but I haven't had much luck finding it.
So far i have the below code
#include <iostream>
using namespace std;
void userData(int&);
int main(){
int a = 0;
int * kmpointer;
int * dayspointer;
userData();
cout << "You ran " << userData(kmpointer) << endl;
cout << "in " << userData(dayspointer) << "days!!" <<endl;
}
void userData(int& i){
cout << "Enter how Many Km's you ran:";
while (true)
{
cin >> kmpointer;
if ((cin) && (kmpointer >= 0) && (inputYear <= 100))
break;
cin.clear();
cin.ignore( 100, '\n' );
cout << "That can't be right!\n";
cout << "Enter how Many Km's you ran:";
}
cout << "How many days in a row did you run?";
while (true)
{
cin >> dayspointer;
if ((cin) && (dayspointer >= 1) && (dayspointer <= 100))
break;
cin.clear();
cin.ignore( 1000, '\n' );
cout << "Thats way to much!";
cout << "How many days in a row did you run? ";
}
}
IMO, you should start with some reading about C++. You are missing some basic concepts and trying too complex exercises for your level.
1
function is not declared/defined.
2
userData is declared accepting a parameter, but used without.
3
The problem you face is related probably with what we call scope: A variable is only existing and visible within its scope (usually enclosed by { and }.
In your case, kmpointer and dayspointerare only visible within the main function and thus, you cannot use them in userData.
To solve that, I suggest you to pass those variables as parameters for userData.
4
Pointers, references, values: They are different. You are saving the user input as a pointer address, which is indeed problematic.
General
In general, your code is full of mistakes. Try a Hello world! and continue from there steps by steps.
Focussing on the specific question you asked (though as observed you have other problems in your code), don't use pointers, use references.
Before we get to that this
cout << "You ran " << userData(kmpointer) << endl;
won't compile, since as you know userData is a void function, so applying << to it makes no sense. It's void so there's nothing to stream.
You said you wanted to pass parameters into the function and let them be changed so do that. Then display the variables afterwards. (Not the "result" of a void function call).
Correctly getting the user input is a separate question which has been answered before.
#include <iostream>
using namespace std;
void userData(int& i, int& j, int& k);
int main() {
int a = 0;
int kmpointer;
int dayspointer;
//Here we call our function, ONCE
userData(a, kmpointer, dayspointer);
//Here we display what values we now have
//after calling the function, ONCE
cout << "You ran " << kmpointer << endl;
cout << "in " << dayspointer << " days!!" << endl;
}
//simplified to demonstrate changes to the reference parameters
void userData(int& i, int& j, int& k) {
//Here we have three parameters which we refer to as i, j and k
// They may have different names ousdie in the calling code
// but this function (scope) neither knows nor cares
j = 42;
k = 101;
}

Irregular code execution

I have been making a program for a local... place, and it is a program that will calculate how much pizza will should be ordered. The problem, however, is not even the calculations, but rather with the files that keep log-in I.D. data.
#include <iostream>
#include <stdlib.h>
#include <iomanip>
#include <fstream>
using namespace std;
string logs[20];
void test(ifstream& IN, string logs[], ofstream& OUT);
void introduction();
int logging_in(string id, string logs[]);
void menu();
string newl = "\n";
string dnewl = "\n\n";
string tnewl = "\n\n\n";
string qnewl = "\n\n\n\n";
string pnewl = "\n\n\n\n\n";
int main()
{
ifstream IN;
ofstream OUT;
string id;
IN.open("loginn.dat");
cout << IN.is_open();
test(IN, logs, OUT);
string sup;
int receive = 0;
introduction();
return 0;
}
void test(ifstream& IN, string logs[], ofstream& OUT)
{
for (int x = 0; x < 20; x++)
{
IN >> logs[x];
}
IN.close();
OUT.open("loginn.dat");
for (int x = 0; x < 20; x++)
{
OUT << logs[x] << " " << "hue" << " ";
}
}
void introduction()
{
string cont;
cout << "Hello. I am the..." << dnewl
<< "Statistical" << newl << "Pizza" << newl
<< "Order" << newl << "Amount" << newl
<< "Diagnostic." << dnewl
<< "Otherwise known as Pizzahand. I will be assisting you to estimate the \namount of pizza that is to be ordered for <INSERT NAME>, as to \neliminate excessive ordering."
<< tnewl;
cout << "Press Enter to continue..." << newl;
cin.get();
}
In theory this is supposed to output the array "logs[]" before executing the rest of the code. This was the case when I had no functions in addition to the main function. As soon as I started to use my next function, "introduction()", the code for reading the text file here
for (int x = 0; x < 20; x++)
{
IN >> logs[x];
}
seemed to be knocked out of order. Instead of performing this task before anything else, it seems as if it does it at the very end of the program as I have tested by outputting its contents while the program was still reading "test()", with no luck. After the main function returns "0", however, I see that my program has outputted data into a test file, "loginns.dat", properly.
It is imperative for my program that this login ID data gets read in at the beginning as when the program transitions to logging in, the data is needed. Also, I have tried placing these arrays and for loops in different locations: in the log-in functions themselves, in the main function, and even another function that I created out of desperation.
I have searched for hours on how to solve this to no avail and experimented myself for plenty of hours more. Every step I took to attempt to fix this lead to more dead ends, or more questions. I am quite the beginner in the sense that this school-year is the first year of studying c++, and I am desperate for an expert opinion (or anyone knowledgeable) to help me face the right direction.
Thank you.
You just need to flush the stream after writing to it:
for (int x = 0; x < 20; x++)
{
OUT << logs[x] << " " << "hue" << " ";
}
OUT.flush();
The reason for this strange behaviour is that file streams don't necessarily write out to files immediately when you write to them. For efficiency reasons, they write the data to an internal memory buffer (an area of memory used by the stream), and then write the buffer contents out to the file all at once when the buffer is flushed. When an application finishes then all of its stream buffers are automatically flushed, which is why you are seeing that the file has been written to after your program finishes. However you can flush them earlier yourself, as shown above. It can also happen when the buffer gets full.
You can also trigger a flush using the endl token, which writes a newline character and flushes the buffer, like this:
for (int x = 0; x < 20; x++)
{
OUT << logs[x] << " " << "hue" << " " << endl;
}