I'm trying to processes values from two text files.One holds a set of chars and the other holds a set of integers.each in their respective places in the text file will amount to one test case.For example the first value that is read in each text file is 1 test case.The values are then used to be checked for variability then Which will then be used as variables through out my code.then in the end prints out a double. The issue is I do not know how to reach that second iteration of test cases. All my code does is read the first values of each text file and prints out the double i need but for only the first test case. As i was typing this out i thought of maybe deleting the values once they are done being used then rerunning the program by having my main in a for loop? suggestions?
#include <iostream>
#include <fstream>
using namespace std;
//function prototypes
char getPackage();
bool vaildPackage(char);
int getHours();
bool validHours(int);
double calculatePakg_A(int);
double calculatePakg_B(int);
double calculatePakg_C(int);
void showBill(double);
int main()
{
char Package = getPackage();
int Hours = getHours();
double bill;
switch (Package)
{
case 'A':bill = calculatePakg_A(Hours);
cout << bill << endl;
break;
case 'B':bill = calculatePakg_B(Hours);
cout << bill << endl;
break;
case 'C':bill = calculatePakg_C(Hours);
cout << bill << endl;
break;
case 'a':bill = calculatePakg_A(Hours);
cout << bill << endl;
break;
case 'b':bill = calculatePakg_B(Hours);
cout << bill << endl;
break;
case 'c':bill = calculatePakg_C(Hours);
cout << bill << endl;
break;
default: cout << "you did not enter a valid Service Plan. \n";
break;
}
return 0;
}
char getPackage()
{
ifstream inputFile;
char a;
inputFile.open("Packages.txt");
do
{
inputFile >> a;
} while (! vaildPackage(a));
return a;
}
bool vaildPackage(char a)
{
return a == 'a' || a == 'A'|| a == 'B' || a == 'b'|| a == 'C' || a == 'c';
}
int getHours()
{
ifstream inFile;
int n;
inFile.open("Hours.txt");
do
{
inFile >> n;
} while (! validHours(n));
return n;
}
bool validHours(int n)
{
return n>=0 && n<= 720;
}
double calculatePakg_A(int hrs)
{
if(hrs <=50)
{
return 15.00;
}
else
{
return (hrs-50) * 2.00 + 15;
}
}
double calculatePakg_B(int hrs)
{
if(hrs <=100)
{
return 20.00;
}
else
{
return (hrs-100) * 1.50 + 20.00;
}
}
double calculatePakg_C(int hrs)
{
if(hrs <=150)
{
return 25.00;
}
else
{
return (hrs-150) * 1.00 + 25.00;
}
}
Package.txt
A a B b C c e c
Hours.txt
50 51 100 101 149 251 750 722
As I'm sure you know, you can read multiple fields from a stream:
ifstream inputFile;
char a;
inputFile.open("Packages.txt");
inputFile >> a;
cout << a << endl;
inputFile >> a;
cout << a << endl;
The reason your code doesn't work is that when control returns from getPackage(), the variable inputFile is deleted, so every time you call that function, it opens the file anew and starts reading from the beginning.
One solution is to make the input stream a static variable, so that it will not be deleted, but will maintain its state from one call to the next:
char getPackage()
{
static ifstream inputFile("Packages.txt");
char a;
inputFile >> a;
return a;
}
I think the only issue here is this.
In the function getPackage()
inputFile.open("Packages.txt");
This opens the file every time you call this function
Due to this, this function is reading the first entry (only) every time.
The same issue with getHours function.
One way out is you can read all entries from the file once into a data structure, say vector and iterate through the vector in the main function.
Another way is open the file(s) in main function and introduce a loop in main that calls these functions. Every time they are called, they would return the next entry from the file. This requires passing the opened file ifstream & as an argument to functions getHours and getPackage
Related
I did my "Hello World", I'm just getting started on my programming adventure with C++. Here is the first thing I've written, what are some ways to get it to end with user input? I'd like a yes or no option that would terminate the program. Also any feedback is welcome, thank you
#include <iostream>
using namespace std;
void Welcome();
void calculateNum();
void tryAgain();
int main() {
Welcome();
while (true) {
calculateNum();
tryAgain();
}
system("pause");
}
void calculateNum() {
float userNumber;
cin >> userNumber;
for (int i = 100; i >= 1; i--) {
float cNumber = i* userNumber;
cout << i << " >>>>> " << cNumber << endl;
}
}
void Welcome() {
cout << "Welcome \n Enter a number to see the first 100 multiples \n";
}
void tryAgain() {
cout << "Try again? Enter another number... ";
}
Here is one option:
Switch to do ... while loop, with the condition at the end.
Make your tryAgain() function return a boolean and put it in the while condition.
In tryAgain function read input from the user, and compare it to expected answers.
First, lets add a new header for string, it will make some things easier:
#include <string>
Second, lets rebuild the loop:
do {
calculateNum();
} while (tryAgain());
And finally, lets modify the function:
bool tryAgain() {
string answer;
cout << "Try again? (yes / no)\n";
cin >> answer;
if (answer == "yes") return true;
return false;
}
Now, there is a slightly shorter way to write that return, but it might be confusing for new learners:
return answer == "yes";
You don't need the if because == is an operator that returns bool type value.
You can change your calculateNum() in the following way:
Change the return value of your calculateNum() function into bool to indicate whether the program shall continue or stop
read the input into a std::string
check if the string is equal to your exit string like 'q' for quit
3.a in that case, your function returns false to indicate the caller that the program shall stop
3.b otherwise, create a stringstream with your string and read the content of the stream into your float variable and continue as you do like now
In your loop in your main function you break if calculateNum() returned false
Here is a simple solution:
#include <iostream>
// Here are two new Includes!
#include <sstream>
#include <string>
using namespace std;
void Welcome();
// Change return value of calculateNum()
bool calculateNum();
void tryAgain();
int main()
{
Welcome();
while (true)
{
if (!calculateNum())
break;
tryAgain();
}
system("pause");
}
bool calculateNum()
{
//Read input into string
string userInput;
cin >> userInput;
//Check for quit - string - here just simple q
if (userInput == "q")
return false;
//otherwise use a std::stringstream to read the string into a float as done before from cin.
float userNumber;
stringstream ss(userInput);
ss >> userNumber;
//and proces your numbers as before
for (int i = 100; i >= 1; i--)
{
float cNumber = i * userNumber;
cout << i << " >>>>> " << cNumber << endl;
}
return true;
}
void Welcome()
{
cout << "Welcome \n Enter a number to see the first 100 multiples \n";
}
void tryAgain()
{
cout << "Try again? Enter another number... ";
}
Having your users input in a string you can even do further checks like checking if the user entered a valid number, interpret localized numbers like . and , for decimal delimitters depending on your system settings and so on.
I input a number in char type variable. like 12 or 22. but, console show me a 1 or 2.
How i get a whole number 12 ,22 in console?
#include <iostream>
int main()
{
using namespace std;
char a = 0;
cin >> a;
cout << a << endl;
return 0;
}
Here is console result.
12
1
C:\Users\kdwyh\source\repos\MyFirstProject\Debug\MyFirstProject.exe(프로세스 18464개)이(가) 종료되었습니다(코드: 0개).
이 창을 닫으려면 아무 키나 누르세요...
The reason I don't use int, string and something is because I want to get both number and Character in one variable.
So I want to see the results of combined numbers and character at the same time.
in that process i can't get a whole number.
#include <iostream>
using namespace std;
int index = 0;
constexpr int pagenum = 10;
void chapterlist(void);
void nextlist(void);
void beforelist(void);
void movechapter(char a);
int main(void)
{
char userin = 0;
bool toggle = 0;
cout << "결과를 볼 챕터를 고르시오." << endl;
chapterlist();
cout << "다음 페이지로 이동: n" << endl;
cin >> userin;
if (userin == 'n')
{
backflash:
while(toggle == 0)
{
nextlist();
cin >> userin;
if (userin == 'b')
{
toggle = 1;
goto backflash;
}
else if (userin == 'n')
continue;
else
{
system("cls");
movechapter(userin);
break;
}
}
while(toggle == 1)
{
beforelist();
cin >> userin;
if (userin == 'n')
{
toggle = 0;
goto backflash;
}
else if (userin == 'b')
continue;
else
{
system("cls");
movechapter(userin);
break;
}
}
}
else
{
system("cls");
movechapter(userin);
}
return 0;
}
void chapterlist(void)
{
int x = 0;
for (x = index + 1; x <= index + 10; x++)
cout << "Chapter." << x << endl;
}
void nextlist(void)
{
system("cls");
cout << "결과를 볼 챕터를 고르시오." << endl;
index = index + pagenum;
chapterlist();
cout << "다음 페이지로 이동: n" << endl;
cout << "이전 페이지로 이동: b" << endl;
}
void beforelist(void)
{
system("cls");
cout << "결과를 볼 챕터를 고르시오." << endl;
index = index - pagenum;
chapterlist();
cout << "다음 페이지로 이동: n" << endl;
cout << "이전 페이지로 이동: b" << endl;
}
void movechapter(char a)
{
cout << "선택한 Chapter." << a << "의 결과입니다." << endl;
}
In movechapter(), console show me a is 1 or 2, not 12, 22.
First, you have to understand what achar type is.
Character types: They can represent a single character, such as 'A' or '$'. The most basic type is char, which is a one-byte character. Other types are also provided for wider characters.
To simplify that, char can only hold one character.
Where as with your code, "12" is actually 2 separate characters, '1' and '2', and that's the reason it would not work.
Instead of declaring a as a char type, you could declare it as an int type, which is a type designed to hold numbers. So you would have:
int a = 0;
However, do note that int often has a maximum value of 2^31.
Or you could use std::string to store character strings. However, do note that if you wish to do any calculations to your string type, you would need to convert them to a number type first:
int myInt = std::stoi(myString);
Edit:
So I have re-checked your code after your update, there is nothing wrong with using std::string in your case. You can still check if user have input n or b by:
if (userin == "n")
Note that you would use double quotation mark, or "letter", around the content that you want to check.
On the other hand, you could use:
if(std::all_of(userin .begin(), userin.end(), ::isdigit))
To check if user have input a number.
Although char is just a number, it's presumed to mean "single character" here for input. Fix this by asking for something else:
int a = 0;
You can always cast that to char as necessary, testing, of course, for overflow.
You should be reading characters into a string, and then converting that string into an int. It would also probably make more sense to use something like getline() to read input, rather than cin >> a.
#include <string>
#include <iostream>
#include <stdexcept>
#include <stdio.h>
int main() {
std::string input_string;
/* note that there is no function that will convert an int string
to a char, only to an int. You can cast this to a char if needed,
or bounds check like I do */
int value;
while(1) {
getline(std::cin, input_string);
/* std::stoi throws std::invalid_argument when given a string
that doesn't start with a number */
try {
value = std::stoi(input_string);
} catch (std::invalid_argument) {
printf("Invalid number!\n");
continue;
}
/* You wanted a char, the max value of a `char` is 255. If
you are happy for any value, this check can be removed */
if (value > 255) {
printf("Too big, input a number between 0-255\n");
continue;
}
break;
}
printf("Number is %hhu\n", value);
}
This is my code.
#include <iostream>
using namespace std;
typedef struct
{
int polski;
int wf;
int matma;
}oceny;
int funkcja_liczaca(int suma, int ile_liczb, int ktory_przedmiot, oceny &temporary);
int main()
{
int suma = 0;
int temp[3];
int ile_liczb_zostalo_wprowadzonych = 0;
oceny database;
string teksty[3] = {"polski: ", "wf: ", "matma: "};
for (int i=0; i!=3; i++)
{
cout << teksty[i] << endl;
while(temp[i]!=0)
{
cin >> temp[i];
if(cin.good()) //floating point exception here. the code don't even step into this one.
{
{
suma = temp[i] + suma;
ile_liczb_zostalo_wprowadzonych++;
if(temp[i]==0){ile_liczb_zostalo_wprowadzonych--;}
}
}else cout << "error";
};
funkcja_liczaca(suma, ile_liczb_zostalo_wprowadzonych, i, database);
suma = 0;
ile_liczb_zostalo_wprowadzonych = 0;
}
cout << "output of struct members in main() \n";
cout << database.polski << endl;
cout << database.wf << endl;
cout << database.matma << endl;
return 0;
}
int funkcja_liczaca(int suma, int ile_liczb, int ktory_przedmiot, oceny &temporary)
{
if(ktory_przedmiot==0){temporary.polski=suma/ile_liczb;cout << temporary.polski << endl;}
if(ktory_przedmiot==1){temporary.wf=suma/ile_liczb;cout << temporary.wf << endl;}
if(ktory_przedmiot==2){temporary.matma=suma/ile_liczb;cout << temporary.matma << endl;}
}
It counts arithmetic average of inputed numbers untill user input 0 which ends loop. then the arithmetic average of thoose numbers is counted in the funkcja_liczaca() and it's saved into the members of struct oceny.
everything works fine but i want to implement something like "stream" check while inputing from keyboard to prevent inputing bad variables into integer type variable.
so inputing 'g' into temp[i] is causing floating point exception. the question is why? cin.good() and cin.fail() is not working.
When you want to deal with errors in the input stream, it's better to read the input line by line as a string and then attempt to extract your data from the string. If extraction of the data from the string is successful, proceed to process the data. Otherwise, attempt to read the next line of text. Here's the core logic for that.
while ( true )
{
cout << teksty[i] << endl;
std::string line;
if ( !getline(cin, line) )
{
// Problem reading a line of text.
// Exit.
exit(EXIT_FAILURE);
}
// Construct a istringstream object to extract the data.
std::istringstream istr(line);
if ( istr >> temp[i] )
{
// Extracting the number was successful.
// Add any additional checks as necessary.
// Break out of the while loop.
break.
}
// Bad input. Continue to the next iteration of the loop
// and read the next line of text.
}
First post ever on this site so spare my life , please.
I'm trying to do a little encryption and decryption program imitating the Enigma cipher/machine from the WW2 (enough history lessons)
So I'm trying to input a number and a letter like so : 1h 2e 3l 4l 5o ;
Because I don't use a cycle I need to write for every variable that I'm adding the number , but what do I do if I have less letters than variables?The only way I can think of is using a cycle which checks if the input is a letter or not.That's why the current code I've written only can be used for specific amount of numbers and letters...
#include <iostream>
#include <limits>
using namespace std;
int main()
{
int opt;
cout<<"Enter 1 for encryption and 2 for decryption. "<<endl;
cin>>opt;
if(opt == 1)
{
int setting1,setting2,setting3,setting4;
char a,b,c,d;
cout<<"_________________________________________________"<<endl;
cin>>setting1>>a>>setting2>>b>>setting3>>c>>setting4>>d;
a+=setting1;
b+=setting2;
c+=setting3;
d+=setting4;
cout<<(char)a<<" "<<(char)b<<" "<<(char)c<<" "<<(char)d<<endl;
}
if(opt == 2)
{
int setting1,setting2,setting3,setting4;
char a,b,c,d;
cout<<"_________________________________________________"<<endl;
cin>>setting1>>a>>setting2>>b>>setting3>>c>>setting4>>d;
a-=setting1;
b-=setting2;
c-=setting3;
d-=setting4;
cout<<(char)a<<(char)b<<(char)c<<(char)d<<endl;
}
if(opt !=1 && opt !=2)cout<<"ERROR!"<<endl;
std::cout << "Press ENTER to continue..."<<endl;
std::cin.ignore( std::numeric_limits<std::streamsize>::max(),'\n');
return 0;
}
Also I was told that the last 2 lines would prevent the .exec from closing after it's done doing it's thing.
I recommend inputting your data in loops (cycles). But before that is accomplished, I suggest using a structure (or class) with an overloaded stream extraction operator.
struct Number_Letter
{
int number;
char letter;
friend std::istream& operator>>(std::istream& inp, Number_Letter& nl);
};
std::istream& operator>>(std::istream& inp, Number_Letter& nl)
{
inp >> nl.number;
if (inp)
{
inp >> nl.letter;
if (!isalpha(nl.letter))
{
// Error recovery for not reading a letter
}
}
else
{
// Error recovery for failing to read number.
}
return inp;
}
Your input loop would be something like:
Number_Letter nl;
while (std::cin >> nl)
{
// process the data
}
For cryptography, you may want to keep the data as a string:
std::string message;
getline(cin, message);
for (unsigned int i = 0; i < message.length(); i += 2)
{
if (!isdigit(message[i]))
{
cerr << "Invalid message type at position " << i << endl;
break;
}
if (i + 1 > message.length())
{
cerr << "Missing letter at end of message.\n";
break;
}
if (!isalpha(message[i+1]))
{
cerr << "Invalid message type at position " << i << endl;
break;
}
}
It sounds like you're trying to check for an unknown sequence of character/integers and need a loop to do the check?
int opt;
cout<<"Enter 1 for encryption and 2 for decryption. "<<endl;
cin>>opt;
if(opt != 1 && opt != 2)
{
cout << "Error" << endl;
return -1;
}
int integer;
char character;
char again;
do
{
cout<<"_________________________________________________"<<endl;
cin>>integer>>character;
if(opt == 1) {
character+=integer;
} else if(opt == 2) {
character-=integer;
}
cout << character <<endl;
cout << "Again (Y)?: ";
cin>>again;
}while(again == 'Y' || again == 'y');
std::cout << "Press ENTER to continue..."<<endl;
std::cin.ignore( std::numeric_limits<std::streamsize>::max(),'\n');
return 0;
Im trying to lean structures and I think I am doing something wrong when I use the structure and trying to call it into a function.
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;
//Structure
struct Inventory
{
int NumberPartsBin;
};
//Function Prototypes.
void choiceMenu();
void AddParts(int &);
void RemoveParts(int &);
int main()
{
char Election;
int choice;
Inventory Parts = {10};
const int Valve_Choice = 1,
Quit_Choice = 2;
I am trying to to resolve this problem with one item, but I will use arrays for 10 items.
do {
choiceMenu();
cin>> choice;
if (choice >= Valve_Choice & choice <= Quit_Choice)
{
switch(choice){
case Valve_Choice:
cout<<"Enter A for Add Parts or R to Romove Parts";
cin >> Election;
if (Election=='A')
{
AddParts(Parts);// My problem is here
}
if else (Election =='R'){
RemoveParts(Parts);}
else{
cout << "Invalid Entry. Try Again";
cin >> Election; }
break;
case Quit_Choice:
cout<<"Program Ending";
return;
else
{
cout<<"Enter a valid choice!!;
cin >> choice;
}
}
}
while (choice >= Valve_Choice & choice < Quit_Choice);
system("pause");
return 0;
// Bin Choice
void choiceMenu()
{
// We use ofstream to create and write on a text file.
ofstream outputFile;
outputFile.open("C:\\Users\\Alexander MR\\Desktop\\CompanyABCPayRoll.txt");
// The headed of the document.
outputFile << " Inventoy\n";
outputFile << " = = = = = = = = \n";
outputFile << " *Choose the part of your preference.\n";
outputFile << " 1. valves = " << Parts.NumberPartsBin << endl;
outputFile << " 11. Choose 2 to quit the Program" << endl;
outputFile.close();
}
I am not sure of my function either.
my function to add parts
void AddParts(int &Parts1)
{
int Enter1;
Parts1.NumberPartsBin = Parts1.NumberPartsBin + Enter1;
}
My function to remove parts
void RemoveParts(int &Parts2)
{
int Enter2;
Parts2.NumberPartsBin = Parts2.NumberPartsBin - Enter2;
}
Reading the question with only parts of the code formatted is quite hard. The first thing I saw was:
void RemoveParts( int &Parts2 ) {
int Enter2;
Parts2.NumberPartsBin = Parts2.NumberPartsBin - Enter2;
}
This makes no sense at all. If Parts2 is an int, then you will never be able to say Parts2.NumberPartsBin. The second thing is int Enter2;. You never give it a value, but in the next line you want to subtract it from something‽
I'm guessing (at least with this function) that you are trying to do something like this:
void RemoveParts( Inventory& inventoryItem, int amountOfParts ) { // inventoryItem is passed by reference, amountOfParts is passed by value
inventoryItem.NumberPartsBin = inventoryItem.NumberPartsBin - amountOfParts;
}
Looking at your code, I'm guessing you're quite new to all of this. I'm no guru, but please:
Capitalize class/struct names and start variable names with a lowercase. ( like parts or election)
If you want to change the value that comes into a function, pass it by reference, but if it is something like an int or a char, simply pass it by value.
p.s. it's if, else if, else and not if else which will otherwise be the next error in your code.