Ok... For an assignment that took 1 minute to read and understand, I wrote all of this code.
Literally, the assignment said get num from user, raise it to power, print results, check if they want to do another number.
main.cpp
Code:
#include <iostream>
#include "user.h"
#include "powerizer.h"
#include "replay.h"
#include "header_footer.h"
using namespace std;
/*
C++ Beginning - Lab 4 - 1307.xxx
April 9, 2010.
A-Option -
Inputs:
User enters number and power
Outputs:
Program prints number raised to power to stdout.
Error conditions are handled during number submission
and answer submission. Option to repeat the program is
included.
*/
int main_driver();
int main(){
// greet the user
print_intro();
// Initiate the main controlling section of the program
main_driver();
// die
return 0;
}
int main_driver(){
int number;
int power;
long int result;
// get number from user
// get power from user
// raise number to power
// print results
// check for replay
do{
// get number and power
cout << "Enter the number to raise to a power." << endl;
number = user_submitted.g_number();
cout << "Enter the power to raise number to." << endl;
power = user_submitted.g_number();
// do it
result = process.raise_number_to_power(number, power);
// print out the results
print_results(number, power, result);
// check for replay
}while(option_for_replay());
return 0;
}
user.h
Code:
/*
* Welcome to user.h. This header file contains routines to
* handle user input regarding the numbers they want to
* work with in the program (and not for user input
* regarding whether or not the user wants to restart
* the program. That is handled by option_for_replay.h)
*/
#include <iostream>
using namespace std;
#define MAX_ELEMENT 20 // max elements in any array in this program.
#define debug 0 // <- make this positive for debug messages.
/*
In an effort to better understand C, I'll use
structures for this assignment. In an effort to write
better code, I've done all of this in an 80x25 terminal
and using vi, which is the most challenging text editor
I've come across so far. Also with a serious attempt at
readable code.
*/
// Build structures for user submitted info
/* user_submitted_entires pertains to the numer, and the power
that the user entered. It contains public functions
for getting a number, and printing number and power. */
struct user_submitted_entries{
// g_number() gets a number and returns it.
int g_number();
private:
// Private variables number and power.
int power;
int number;
}user_submitted; // <-- create an object user_submitted that can be accessed globally.
/* user_input pertains to the validity of the user's submissions.
it contains public functions to prepare the array for
the users entry, to check it, to get the length,
and to convert the array to an integer. */
struct user_input{
// dot_array() goes from 0 to max_element filling the array with '.'s
void dot_array(char array[]);
// validate_entry() checks to see if the users submission was useable in the
// rest of the program. It returns 1 if the answer is bad, 0 if it is good.
int validate_entry(char ent_num[]);
// g_num_of_elements_in() scans the array for things that aren't '.'s, and returns where the last one was found.
int g_num_of_elements_in(char num[]);
// make_char_array_a_number() takes an array and its length, and converts it into an integer.
int make_char_array_a_number(char num[], int num_of_elements);
}input; // <-- create object input that can be accessed globally.
// I was happy to learn that part of an idea
// I came up with for multiplying numbers
// in a matrix that is designed to
// replicate physically writing math
/* on a piece of notebook paper would work in this program.
( the matrix-math program is useful because I can store more than
2^32 in a 100 element vector.. a lot more
in the end the idea would simulate long-hand multiplication,
addition, subtraction, and division of problems that could be
multiple pages wide.
--- UPDATE --- Professor says Arrays != Matrices
For example -
2342342342378297834234
4534534534534543523423
*_____________________
//////////// A ////////
/////////// lot of//////
//////////work here///
+_____________________
/// bigger answer here ///
// but remember that everything
// you see is an element in the
// matrix // )
*/
/*
this function moves through a char array,
strips each element of its ASCII code, multiplies the
the element by the power of 10 represented by its
place in the array (123 = 3*1+2*10+1*100), and
assigns the result to "number", which is then returned.
The char array is started from the end, because 123 is
stored in elements [0][1][2] respectively. I did this
because I didn't know how to handle situations where
a user is entering an integer number, but instead inputs
a letter or some other nonsense. The results were generally overflows.
*/
int user_input::make_char_array_a_number(char num[], int num_of_elements){
if(debug){ cout << "Entered make_char_array_a_number()" << endl; }
int converted_to_number = 0;
int current_power_of_ten;
int current_element;
for( current_element = num_of_elements, current_power_of_ten = 1;
--current_element >= 0;
current_power_of_ten *= 10 ){
converted_to_number += (num[current_element] - '0') * current_power_of_ten;
}
if(debug){ cout << "Leaving make_char_array_a_number()." << endl; }
return converted_to_number;
}
// get the number, and make sure it is a number!
int user_submitted_entries::g_number(){
char entered_num[MAX_ELEMENT];
int gotten_number;
int length;
if(debug){ cout << "Entered g_number()." << endl; }
// prompt toggle changes the prompt from default friendly to
// "restart and enter the right information" mode after the first run through the program
// because, presumably, if you come back through for any reason, it is because you entered something wrong.
int prompt_toggle = 0;
do{
if(prompt_toggle == 0){
cout << ":";
}else{
cout << "Positive Entries Only" << endl;
cout << ":";
}
prompt_toggle++;
if(debug){ cout << "In g_number() -> dotting array" << endl; }
/* to avoid having the array cluttered with old answers, especially
in the case of wrong answers, it is necessary to clean the array
before each use. I hereby state that being full of periods is being clean.*/
input.dot_array(entered_num);
if(debug){ cout << "In g_number() -> Done dotting array" << endl; }
cin >> entered_num;
/*
if entered_num turns out to be
something other than a number or a '.',
then validate_entry will be positive.
*/
if(debug){ cout << "In g_number() -> validating entry" << endl; }
}while( input.validate_entry(entered_num) );
if(debug){ cout << "In g_number() -> Entry validated" << endl; }
/* g_num_of_elements_in searches from 0 to MAX_ELEMENT
for a period. This will indicate the end of the
entered number. It depends on validate_entry being called
before it. Convenient, since validate_entry is designed
to fit in the condition of a do{}while() loop.
g_num_of_elements_in does not care what you entered, just
how much you entered. As opposed to validate_entry
which does not care about how much you entered, but what
you actually entered.
*/
if(debug){ cout << "In g_number() -> Getting Length" << endl; }
length = input.g_num_of_elements_in(entered_num);
if(debug){ cout << "In g_number() -> Length Obtained" << endl; }
/*
this aptly named function does exactly
what it says it does... as it tears apart
an array of characters, walks through
each one and multiplies it by the
power of 10 represented by its position
in the array, the results are stored in an integer.
It returns that integer.
*/
if(debug){ cout << "In g_number() -> Making char* to number" << endl; }
gotten_number = input.make_char_array_a_number(entered_num, length);
if(debug){ cout << "In g_number() -> char* is now a number." << endl; }
cout << "You entered [" << gotten_number << "]\n" << endl;
if(debug){ cout << "Leaving g_number()" << endl; }
// Finally, return the number you got.
return gotten_number;
}
/*
my answer to the question of, "How do I initialize an array
so that it is uniform except for situations I'm looking for,
and that will allow me to perform mathematical operations on
each element without any issues was to intialize the character
array with periods, and use my tests based on whether or not
something was a period, a number, or something I don't want.
*/
// Write to array[i] with periods.
inline void user_input::dot_array(char array[]){
if(debug){ cout << "Entered dot_array()" << endl; }
int current_element;
for(current_element = MAX_ELEMENT;
--current_element >= 0; ){
array[current_element] = '.';
}
if(debug){ cout << "Verification of write to array" << endl;
cout << "Start value [" << array[0] << "] End value [";
cout << array[MAX_ELEMENT - 1] << "]" << endl;
}
if(debug){ cout << "Leaving dot_array()" << endl; }
}
/*
This exceedingly inefficient, but Russian Reliable method
for finding the length of an array is part of another idea I have.
It works by going from one end of an array of dots to the other,
looking for things that aren't dots. Mostly this is a result
of my lack of understanding when it comes to reliably validating data.
Though I will say this.. The issue with my user input method
is not caused by cin or by the looping structure. It is caused by
some buffer I am not aware of that retains the information even
when my program rejects it. Some buffer that feeds cin. I don't know
if it is operating system specific, or if it is specific to C++,
but I have the same issue when I don't use cin (ex, happens with getch, getchar, scanf, etc)
so stdin must have a buffer or something that bridges stdin to the program.
*/
inline int user_input::g_num_of_elements_in(char check[]){
if(debug){ cout << "Entered g_num_of_elements_in()" << endl; }
int found_length;
int cur_elem;
// go from 0 to max_element looking for things that are '.'
for( cur_elem = 0; cur_elem < MAX_ELEMENT; cur_elem++ ){
if( check[cur_elem] == '.'){
found_length = cur_elem-1;
if(debug){
cout << "Found Last digit in element[";
cout << cur_elem-2 << "]";
cout << "\nRETURNING: " << found_length;
cout << endl;
}
if(debug){ cout << "leaving g_number()\n"; }
return found_length;
}else{
// do nothing because it is not the number, but part of the number.
}
}
if(debug){ cout << "Failed in g_num_of_elements_in()." << endl; }
return 0;
}
// check to make sure the input is valid.
inline int user_input::validate_entry(char ent_num[]){
if(debug){ cout << "Entered validate_entry" << endl; }
int i;
// TEST CONDITIONS FOR VALIDITY
bool failed_entry = false;
for(i = 0; i < MAX_ELEMENT && ent_num[i] != '\0'; i++){
if( !(ent_num[i] == '.') && !(isdigit(ent_num[i]))){ failed_entry = true; }
}
if(debug && !failed_entry){ cout << "Answer was good." << endl; }
return failed_entry;
}
replay.h
Code:
#include <iostream>
#include <cctype>
using namespace std;
// Brain freeze at 4AM..
// super obvious example ensues.
/*
Basically, allow the user to enter whatever.
After that, check only the first element of the char array
that the user just filled with whatever. If it isn't
yes or no, ask again (but also switch the message.)
First pass through for the message is a greeting,
the next is a courteous error message.
*/
int option_for_replay(){
char users_response_to_question[100];
char extracted_answer;
bool wrong_answer = false;
do{
if(!wrong_answer){
cout << "Would you like to go again? enter Yyes or Nno\n";
}else{
cout << "Please enter a valid response of Yyes or Nno" << endl;
}
cin >> users_response_to_question;
extracted_answer = users_response_to_question[0];
if( isalpha( extracted_answer ) ){
if( extracted_answer //is
== 'y' || //or
extracted_answer //is
== 'Y' ){
// then the answer is yes
cout << "Ok, restarting the program.\n\n";
return true;
}else if( extracted_answer //is
== 'n' || //or
extracted_answer //is
=='N' ){
// then the answer is no
cout << "Shutting down the program.\n" << endl;
return false;
}else{
wrong_answer = true;
}
}else{
wrong_answer = true;
}
}while(wrong_answer);
cout << "Never should have gotten here.. go ahead and restart then." << endl;
return true;
}
powerizer.h
Code:
#include <iostream>
using namespace std;
// Struct declaration and definition
/*
pretty basic way of raising num to pow.
take the number that has been interrogated
thoroughly, and multiply it by its power, which has
also been interrogated.
Store that result in number_raised_to_power;
*/
struct powerizer{
// variable for storing the results
long int number_raised_to_power;
// function for factorializing a number
int raise_number_to_power(int &num, int &pow);
}process; // object process to be accessible globally.
int powerizer::raise_number_to_power(int &base, int &pow){
int p = pow;
if(debug){ cout << "Entered raise_number_to_power(int base, int pow)" << endl; }
// number_raised_to_power is assigned 1
// because its first use is in multiplication.
// pow controls the loop, num is the base
number_raised_to_power = 1;
for( ; --p >= 0; ){
number_raised_to_power *= base;
if(debug){ cout << pow << endl; }
}
return number_raised_to_power;
if(debug){ cout << "Leaving raise_number_to_power()" << endl; }
}
header_footer.h
Code:
#include <iostream>
using namespace std;
// Print welcome screen
void print_intro(){
cout << "\n\n==================================================================" << endl;
cout << "Welcome to Jonathan Findley's Powerizer v1.00" << endl;
cout << "Part of C++ Lab 4 on loops, powers, and that sort of thing...." << endl;
cout << "Enter the number you want to raise to a power, " << endl;
cout << "and the program will print the result after exponentiation." << endl;
cout << "==================================================================\n" << endl;
}
// Print results
void print_results(int &number, int &power, long int &result){
cout << "======================================================" << endl;
cout << number << " raised to the power of ";
cout << power << " is equal to ";
cout << result;
cout << endl;
cout << "======================================================" << endl;
}
|