Beginner Programmer needs help

F

Foxy Kav

Hi everyone, Im currently doing first year UNI, taking a programming
course in C++, for one project i have to create a simple array
manipulator... that i have done, but i cant figure out how to make the
ESC key quit the called function when ever the user inputs data. The
description was : ESC drops back to the main menu in case the user
gets locked up or wants to start over again, ESC should provide a fool
proof way to exit back to the main menu from anywhere in the program.

Here's my code:

#include <iostream>
#include <cstdlib>
#include <conio.h> // For getsch()
#include <cstring> // For strlen()

using namespace std;

#define MAXSIZE 200 // Defining maximum range of the array
stringarray, emptystring and copystringarray.
#define ESC 27

// Program functions.
void enter() ; // Enter string into array function.
void display(); // Display array contents function.
void erase() ; // Earse contents of array function.
void displaychar() ; // Display character at location function.
void empty() ; // Is the array empty function.
void display10char() ; // Display the first 10 characters of the array
function.
void displayrange() ; // Display characters from array within a given
range function.
void replacechar() ;// Charcter to replace function.
void reverse() ; // Reverse string function.

// Declaring global variables.

// Global variables for enter array.
char stringarray[MAXSIZE] ; // Array to hold the string.

// Global variables for earse array.
char emptystring[MAXSIZE] = "\0" ; // Empty array to copy to
stringarray.

// Global variables for display characater at location.
int length ; // The length in numbers of the array.

// Global variables for is the array empty function.
int test ; // Testing if character is a space.

// Global varaible for reverse string funtion.
char copystringarray[MAXSIZE] = "" ; // Copy of orginal array +
contents.

int main() { // Start main function.

// Declaring variables for main function.
char menuselect ; // Menu selction character.

for(;;) { // Start for lop for menu.
do { // Start do loop for menu.

cout << " String Manipulation: Lab 2 by Kylie Kavanagh 3052463
\n \n" ;
cout << " e) Enter data into the array \n" ;
cout << " d) Display current contents of array \n" ;
cout << " r) Erase current contents of the array. \n \n" ;

cout << " c) Display chracter at location specified \n" ;
cout << " i) Is the array empty? \n" ;
cout << " t) Display the first 10 characters of the array \n"
;
cout << " f) Display characters in range specified \n \n" ;

cout << " j) Replace specified characters with other specified
characters \n \n" ;

cout << " v) Display the string in reverse order \n" ;

cout << " q) Quit this program \n \n" ;

cout << " ESC - Go back to main menu \n" ;

cout << " \n This is the current array contents: " <<
stringarray << "\n" ;

cout << " \n Enter selection: " ;
menuselect = getch() ;

} while (menuselect < 'a' || menuselect > 'z' && menuselect !=
'q') ;

if(menuselect == 'q') break;

cin.ignore(); // Clearing cin buffer.
cout << "\n" ;


switch(menuselect) { // Start switch statement for the menu.

case 'e': // Enter data into the array.
enter() ; // Calling function enter().
break ;

case 'd': // Display current contents of array.
display() ; // Calling function display().
break ;

case 'r': // Earse current contents of array.
erase() ; // Calling function erase() .
break ;

case 'c': // Display character at location number:
displaychar() ; // Calling function displaychar().
break ;

case 'i': // Is input array empty?
empty() ; // Calling function empty().
break ;

case 't': // Display first 10 characters of input array.
display10char() ; // Calling function display10char().
break ;

case 'f': // Display characters in range.
displayrange() ; // Calling function displayrange().
break ;

case 'j': // Replace 'g' with 'h'.
replacechar() ; // Calling function replacechar().
break ;

case 'v': // Display string in reverse order.
reverse() ; // Calling function reverse().
break ;

} // End switch statement for menu.

} // End infinite for loop for menu.

return 0;

} // End main function.

void enter() { // Start enter string into array function.
cout << " Enter string into array: " ;
cin.ignore(); // Clearing cin buffer.
cin.getline(stringarray , MAXSIZE , '\n') ;
// if (cin.getline(stringarray) == ESC) return ;
cout << "\n You entered the string : \n " ;
cout << stringarray << ends;
cout << "\n \n" ;
system("PAUSE");
} // End enter string into array function.

void display() { // Start display contents of array.
cout << " Display contents of array : \n " ;
cout << stringarray << ends;
cout << "\n \n " ;
system("PAUSE");
} // End display contents of array.

void erase(){ // Start of erase contents of array function.
cout << " Current contents of array : \n " ;
cout << stringarray << ends;
cout << "\n \n" ;

strcpy(stringarray , emptystring);

cout << " Contents of array after erasure: " ;
cout << stringarray << ends;
cout << "\n \n" ;

system("PAUSE");
} // End of erase contents of array function.

void displaychar() { // Start display character at location function.

int location ; // Location number of character of array to display.

cout << stringarray << "\n" << ends ; // Displaying the array.

length = strlen(stringarray); // Calculkating the length of the
array.

cout << " \n Enter a location number within the length of the
array (between 1 and " << length << "): " ;
cin.ignore(); // Clearing cin buffer.
cin >> location ;

while(location >= length)
{ // Start while loop.
cout << " \n You did not enter a location number
within the length of the array (between 1 and " << length << ")" ;
cout << " \n Try again: " ;
cin.ignore(); // Clearing cin buffer.
cin >> location ;
} // End while loop.

cout << " \n The character at the location number " << location <<
" is: " << ends; ;
cout << stringarray[location -1] << ends ;
cout << "\n" ;

system("PAUSE");
} // End display character at location function.

void empty() { // Start is the array empty function.

length = strlen(stringarray) ; // Calculating the length of the
array.
test = isalnum(stringarray[0]) ;//test if srray is only a string

if (length > 1)
{ // Start if statement.
cout << " The string is not empty. \n The contents of the
string is: " << stringarray << "\n" ;
} else { // End if statement, start else staement.

if(test != 1)
{ // Start if statement.
cout << " The string is empty. \n There
is nothing in the string, as shown by displaying the string. \n
Contents of string :" << stringarray << "\n" ;
} else { // End if statement, start else
statement.
cout << " The string is not
empty. \n The contents of the string is: " << stringarray << "\n" ;
} // End else statement.

} // End else statement.

cout << "\n" ;
system("PAUSE");
} // End is the array empty function.

void display10char() { // Start display the first 10 characters of the
array function.
cout << " The first ten characters of you array is: " ;
for(int i = 0 ; i < 10 ; i++) cout << stringarray ; //
Displaying the character at i.
cout << "\n" ;
system("PAUSE");
} // End display the first 10 characters of the array function.

void displayrange() { // Start display characters from array within a
given range function.

int startlocation ; // Start location for show array.
int endlocation ; // End location for show array.
int i ; // Control variable for the for loop.

length = strlen(stringarray) ; // Calculating the length of the
array.

cout << " The string is " << length << " characters long. \n From 1
to " << length << " is your valid range. " ;

cout << " \n Enter the start of the range for the array to be shown:
" ;
cin.ignore();
cin >> startlocation ; // Enter start location number.
while (startlocation > length) // Testing if the start location is
within the array length.
{ // Start while loop.
cout << " \n The start location you entered was not in the
arrays range. \n The arrays range is 1 - " << length << " \n Re-enter
the start of the range for the array to be shown: " ;
cin.ignore(); // Clearing cin buffer.
cin >> startlocation ; // Enter start location number.
} // End while loop.

cout << " \n Enter the end of the range for the array to be shown: "
;
cin >> endlocation ; // Enter end location number.
while (endlocation > length) // Testing if the end location is
within the array length.
{ // Start while loop.
cout << " \n The end location you entered was not in the
arrays range. \n The arrays range is 1 - " << length << " \n Re-enter
the end of the range for the array to be shown: " ;
cin.ignore(); // Clearing cin buffer.
cin >> endlocation ; // Enter end location number.
} // End while loop.

while(startlocation > endlocation)
{ // Start while loop.
cout << " \n The start location must be a smaller number than
the end location within \n the valid range : 1 - " << length << " " ;

cout << " \n Enter the start of the range for the array to be
shown: " ;
cin >> startlocation ; // Enter start location number.
while (startlocation > length) // Testing if the start
location is within the array length.
{ // Start while loop.
cout << " \n The start location you
entered was not in the arrays range. \n The arrays range is 1 - " <<
length << " \n Re-enter the start of the range for the array to be
shown: " ;
cin.ignore(); // Clearing cin buffer.
cin >> startlocation ; // Enter start
location number.
} // End while loop.

cout << " \n Enter the end of the range for the array to be
shown: " ;
cin >> endlocation ; // Enter end location number.
while (endlocation > length) // Testing if the end
location is within the array length.
{ // Start while loop.
cout << " \n The end location you
entered was not in the arrays range. \n The arrays range is 1 - " <<
length << " \n Re-enter the end of the range for the array to be
shown: " ;
cin.ignore(); // Clearing cin buffer.
cin >> endlocation ; // Enter end
location number.
} // End while loop.

} // End while loop.

cout << " \n Your selected range was: " << startlocation << " to "
<< endlocation ;
cout << " \n The contents of this range is : " ;
for(i = (startlocation -1 ) ; i < endlocation ; i++) cout <<
stringarray ; // Displaying the character at i.
cout << "\n \n" ;

system("PAUSE");
} // End display characters from array within a given range function.

void replacechar() { // Charcter to replace function.

char chartoreplace ; // Charcter to replace.
char chartoreplacewith ; // Charcter to replace with.
int dectect ; // Control varaibel for sorting loop

cout << " This is you current string: " << stringarray ;
cout << " \n Enter the character you wish to replace (g): " ;
cin.ignore(); // Clearing cin buffer.
cin >> chartoreplace ;

cout << " \n Enter the chracter you wish to replace (g) with (h):
" ;
cin.ignore(); // Clearing cin buffer.
cin >> chartoreplacewith ;

cout << " Replace " << chartoreplace << " with " <<
chartoreplacewith << "\n" ;


length = strlen(stringarray); // Calculating the length of the
array.

cout << "\n This is your changed string: " ;

for(dectect = 0 ; dectect < length ; dectect++)
{ // Start for loop.
if (stringarray[dectect] == chartoreplace)
stringarray[dectect]= chartoreplacewith ;
cout << stringarray[dectect] ;
} // End for loop.

cout << "\n" ;
system("PAUSE");
} // Charcter to replace function.

void reverse() { // Start reverse string function.

char *startofarray ;// Pointer at the start of the string.
char *endofarray ; // Pointer at the end of the string.
char temporary ; // Temporary storage of array elemnet while swapping
around.

cout << " Current array contents: " << stringarray << "\n" ;

/*

strcpy(copystringarray, stringarray) ; // Copying string to keep
orignal string and reverse the copied string.
length = strlen(copystringarray) ; // Finding the length of the
copied string.

startofarray = copystringarray ; // Giving the pointer the
addresss of the start of the array.
endofarray = &copystringarray[length - 1] ; // Giving the pointer
the address of the end of the array, minus the null character.

while (startofarray < endofarray) // Compares start and end
pointer for the condittion expression.
{
temporary = *startofarray ;
*startofarray = *endofarray ;
*endofarray = temporary ;

startofarray++ ; // Moves the pointer up one in the
array index.
endofarray-- ; // Moves the pointer down one in the
array index.
} // End of while loop.

cout << "\n Reversed array: " << copystringarray << "\n" ;
cout << "\n" ;

*/

length = strlen(stringarray) ; // Calculating the length of the
array.

cout << " Your array backwards: " ;
for(int i = length -1 ; i >= 0 ; i--) cout << stringarray ;
// Displaying the character at i.
cout << "\n" ;

system("PAUSE");
} // End reverse string function.
 
N

Niels Dybdahl

manipulator... that i have done, but i cant figure out how to make the
ESC key quit the called function when ever the user inputs data.

The ESC key enters a character with the value 27. You can test for that
exactly like you test for 'q'.

Niels Dybdahl
 
O

osmium

Foxy said:
Hi everyone, Im currently doing first year UNI, taking a programming
course in C++, for one project i have to create a simple array
manipulator... that i have done, but i cant figure out how to make the
ESC key quit the called function when ever the user inputs data. The
description was : ESC drops back to the main menu in case the user
gets locked up or wants to start over again, ESC should provide a fool
proof way to exit back to the main menu from anywhere in the program.
<snip>

Foolproof is a nasty word. You will have to use a new approach to getting
input data. For example, you do a cin to location which is an int. If the
user enters a non int you have a problem. I would write a separate function
which reliably gets input data. It would get a string, perhaps using
getline,and would constantly be looking for the escape character. If no
ESC is found, it parses the input and does any necessary conversion.

BTW. I doubt if the ignore() you have works.
It would be nicer without the gratuitous comments.

This is not the easiest assignment ever made in a first course in
programming.
 
K

Karl Heinz Buchegger

osmium said:
Foolproof is a nasty word. You will have to use a new approach to getting
input data. For example, you do a cin to location which is an int. If the
user enters a non int you have a problem. I would write a separate function
which reliably gets input data. It would get a string, perhaps using
getline,and would constantly be looking for the escape character. If no
ESC is found, it parses the input and does any necessary conversion.

BTW. I doubt if the ignore() you have works.
It would be nicer without the gratuitous comments.

This is not the easiest assignment ever made in a first course in
programming.

That's what I thought too. Doing user input in a 'foolproof' way is
surprisingly hard. Especially the assignments request to bring back
the user to the main menu from everywhere in the program by pressing
ESC means a lot of work. Every function constantly has to check for
this special case and direct all callers to immediatly return, which
means they also have to check for that special case. That is unless
the OP has already learned about exceptions (which I seriously doubt),
which greatly simplifies stack unwinding in this case.
 
O

osmium

Karl said:
That's what I thought too. Doing user input in a 'foolproof' way is
surprisingly hard. Especially the assignments request to bring back
the user to the main menu from everywhere in the program by pressing
ESC means a lot of work. Every function constantly has to check for
this special case and direct all callers to immediatly return, which
means they also have to check for that special case. That is unless
the OP has already learned about exceptions (which I seriously doubt),
which greatly simplifies stack unwinding in this case.

Perhaps setjmp longjmp would be helpful, perhaps not. And even after all
this work it still assumes the computation is trivial. If there was some
serious computation she would have to intercept the keyboard calls to
provide an interrupt. I worked on the idea that any computation was
essentially instantaneous.
 
C

Christopher Benson-Manica

Niels Dybdahl said:
The ESC key enters a character with the value 27. You can test for that
exactly like you test for 'q'.

This assumes that the character set is ASCII, which may or may not be
true.
 
F

Foxy Kav

Thanxs everyone for your help, i've decied to change my menuslection
to cin from getch(), then delete all but one cin.ingore(), i kept the
one just before cin.getline(), that seems to have gotten rid of my
other problem, as for the the ESC key, i still have no idea ... but
thanxs for trying.

Foxy Kav
 
O

osmium

osmium said:
<snip>

Foolproof is a nasty word. You will have to use a new approach to getting
input data. For example, you do a cin to location which is an int. If the
user enters a non int you have a problem. I would write a separate function
which reliably gets input data. It would get a string, perhaps using
getline,and would constantly be looking for the escape character. If no
ESC is found, it parses the input and does any necessary conversion.

Gdday,

After further thought, the above suggestion is not good enough. The getline
approach only detects Escape followed by [Enter] which is surely not
foolproof. Next plan, use getch() and read a character at a time until you
have something you can convert or process. But this has the side ffect of
requiring that your program handle the back space character. Not too bad.
But you must also handle things such as the left arrow and this requires
special fiddling to even gain access to it. There might be some highbred
approach that would work but I remember on my platform that getch() and I/O
streams interact badly. ISTR that getch does not actually get a character,
it is still there insofar as the streams logic is concerned. You need a
really good write-up on getch for *your* platform. Really good write-ups on
most anything, in my experience, are as scarce as hens teeth. Write ups
often ignore or downplay side effects. In my experience the interesting
(hard) part of programming is about 80% side effects and 20% intended
effects. The introduction of the non-standard getch makes the solution off
topic on this newsgroup so any further questions should probably be directed
to a platform specific newsgroup. A good thourough search of google
*groups* is in order.

An entirely different approach would be to trap the Escape character and
tease or coerce it into producing an interrupt to your (main) program.

Unless there is something I am not aware of, you seem to be enrolled in a
sink or swim course designed to separate the sheep from the goats at a very
early stage. I would be astonished if more than one student turns in a
program that meets the specification. And that one person would almost
certainly be someone who started programming at nine years old or something;
someone who is only taking the course to get the credit, not to actually
learn something.
 
D

Dave Moore

Karl Heinz Buchegger said:
That's what I thought too. Doing user input in a 'foolproof' way is
surprisingly hard. Especially the assignments request to bring back
the user to the main menu from everywhere in the program by pressing
ESC means a lot of work. Every function constantly has to check for
this special case and direct all callers to immediatly return, which
means they also have to check for that special case. That is unless
the OP has already learned about exceptions (which I seriously doubt),
which greatly simplifies stack unwinding in this case.


Well .. FWIW, Stroustrup's The C++ Programming Language 3rd Edition
gives a pretty robust and simple framework for accepting
character-wise input in section 21.3.5 .. not exactly suited for the
OP's application, but it should give her a solid start for that part
of the problem. As long as she does the input character-wise in a
similar way, detecting the ESC should be a snap. Getting back to the
main-menu is (as you say) another matter -- but I would say it is not
*that* hard since she is not using user-defined classes (and hence
constructors) yet .. also, she has no static variables defined in any
of her functions. So, since her call tree is only ever one layer
deep, she only needs to use a return statement to get back to the
main-menu immediately after the ESC-press is detected. The only
question is what state to leave the array in after such an ESC-press
... for example, if some data was entered just before the ESC-press,
does she want to leave it in the array, or return the array to the
state it was in before the last call .. I would prefer the latter.

So adding some code like:

char c;
cin.get(c);
if (c==ESC) {// using her somewhat inadvisable definition
// do clean up of array
return;
}
else {
// rest of her code
}

should get her on the right track.

Note that I am (of course) not advocating this as a general solution
.... using exceptions is way better .. but the OP is doing a homework
problem here, not designing life support for the space station.
Hopefully she will progress significantly in her studies before she is
given such a task. Also, I doubt if her prof meant foolproof in the
sense of "still works if the hard-drive is stolen by a rabid monkey",
as intimated by other posters in this thread.

HTH, Dave Moore
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,225
Members
46,815
Latest member
treekmostly22

Latest Threads

Top