Thread: Simple check/deposit exercise in C

  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    18

    Simple check/deposit exercise in C

    I'm teaching myself C atm, reading online tutorials and doing exercises at the end of the chapters. What I've written is a program that reads in either check/deposit and adjusts the amount in the bank account. For example, deposit 1000, deposits 1000 in the bank.

    Explanation of some of the code:

    The function separator is used to separate the command "deposit/check" from the amount to deposit. How it does this is it will scan the input string for letters and put it in a char array. To scan the amount to deposit in the same line, the loop also searches for char numbers and converts it to an int within the same loop. The function also compares user input to the strings "check" and "deposit".

    The function mystrcmp works like strcmp.

    Here is the code:
    Code:
    #include <stdio.h>
    
    int bankAccount = 1000;
    
    main()
    {
    	int i, c;
    	char input[25];
    	
    	while ( 1 )
    	{
    		printf("Enter a check or deposit with the amount or 'q' to quit: ");	
    		
    		if ( (c = getchar() ) == 'q' )
    			break;
    		
    				
    		getLine( input, 25 );		        //gets input
    		separator( input );		        //separates command and amount
    		
    		printf("Balance: %d\n", bankAccount);   //prints the balance after each loop
    		
    	}
    }
    
    //Reads the input line
    int getLine( char array[], int max )
    {
    	int i = 0; 				        //incrementer
    	int c;					        //holds char
    	max = max - 1;					//for null zero
    	
    	while ( (c = getchar() ) != EOF )
    	{
    		if ( c == '\n')				//if end of line, break
    			break;
    		if ( i < max )				//if less than max, put in array
    		{
    			array[i] = c;
    			i++;
    		}
    		
    		if ( (c == EOF) && (i == 0) )
    			return EOF;
    		
    	}
    	
    	array[i] = '\0';				
    	return i;
    }
    
    
    int separator( char array[] )
    {
    	char command[20];				//will hold either deposit or check
    	char amount[20];				//holds amount, but in char
    	char deposit[] = "deposit";				
    	char check[] = "check";			
    	int i, digit, num, retVal = 0;
    
    	for ( i = 0; array[i] != '\0'; i++ )
    	{
    		if ( array[i] >= 97 && array[i] <= 127 )	//if between a-z, no caps
    		{
    			command[i] = array[i];		        //put letter in array
    			printf("Entered %s\n", command);
    		}
    		if ( array[i] >= 48 && array[i] <= 57 )		//if between 0-9
    		{
    			amount[i] = array[i];
    			digit = amount[i] - '0';	        //converts character int to
    			retVal = retVal*10 + digit;	        //actual int, i.e. '123' 
    		 }                                                    					   
    	}
    
    	printf("Entered %s\n", command);			//test commands to debug
    	printf("Entered %d\n", retVal);			        //test commands to debug
    
    	if ( mystrcmp( command, deposit ) == 0 )
    	{
    		bankAccount = bankAccount + retVal;	        //add to bank account 
    	}
    	
    	if ( mystrcmp( command, check ) == 0 )
    	{
    		bankAccount = bankAccount - retVal;	        //subtract from bank
    	}
    		
    	return 0;
    }
    
    //This is my personal string comparison function.
    mystrcmp(char str1[], char str2[])					
    {
    	int i = 0;
    
    	while(1)
    	{
    		if(str1[i] != str2[i])
    			return str1[i] - str2[i];
    		if(str1[i] == '\0' || str2[i] == '\0')
    			return 0;
    		i++;
    	}
    }
    So my problems are:

    1) The if statement to quit the program reads the first letter and if it is 'q', then the program exits. But what happens is that if I type "deposit", it reads the first char 'd' and then passes off 'eposit' to the function below. How do I overcome this?

    2) I have no idea what's going on here, command[20] does not work, but command[10] does. Must be something with the length of the array.
    Here is an output with command[20]:
    Enter a check or deposit with the amount: check 1000
    Entered cX���
    Entered ch���
    Entered che��
    Entered chec�
    Entered check
    Entered check
    Entered 1000
    Balance: 1000


    Here is an output with command[10]:
    Enter a check or deposit with the amount: check 1000
    Entered c
    Entered ch
    Entered che
    Entered chec
    Entered check
    Entered check
    Entered 1000
    Balance: 0



    I think what I've done here is make a simple program overcomplicated. Nevertheless, I would like to debug it first, then rewrite the code so that it's more logical.

    Thanks for taking the time to read this.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    Enter a check or deposit with the amount: check 1000
    Entered cX���
    Entered ch���
    Entered che��
    Entered chec�
    Entered check
    Entered check
    Entered 1000
    Balance: 1000
    Code:
    		if ( array[i] >= 97 && array[i] <= 127 )	//if between a-z, no caps
    		{
    			command[i] = array[i];		        //put letter in array
    			printf("Entered %s\n", command);
    		}
    command is not a qualified string. It's just an uninitialized array. It's pure luck that it "worked" with its size as 10.


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    A couple things first:
    • It's int main(void) and return an int at the end.
    • Always specify a return type and parameter list (or lack there of) for your functions explicitly. That is, mystrcmp needs an explicit "int" in front of it.
    • Either define your functions before you use them, or put a prototype at the top of the file


    The first two things on there make me think some of the tutorials/books you're using are a bit outdated, so be wary.

    As for your "eposit" issue, getchar removes the letter from the input buffer, so when you call it in the if statement you highlighted, you remove the first letter, whether it's a 'q', a 'd' or anything else. You need to call getLine first, then check if input[0] is a 'q'.

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Code:
    #include <stdio.h>
    #include <math.h>
    
    int main (void)         // correct entry point function
      { float Balance = 0;
        float Transaction = 0;
    
        printf("Enter the initial balance :  " );
        scanf("%f", &Balance);
    
        do
          { Balance += Transaction;
            printf("\n Running balance = %.2f", Balance);
            printf("\n Enter transaction ( + = Deposit - = Withdrawl 0 = Exit) :  "); 
            scanf("%f",&Transaction) ;
            getchar(); }
        while (Transaction != 0 );
    
       printf("\n\nFinal balance = %.2f\n\n", Balance);
       printf("Press Enter to close...");
       getchar();
    
       return 0; }  // correct program exit.
    Last edited by CommonTater; 09-14-2011 at 04:44 PM. Reason: Test and repost...

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by CommonTater View Post
    Code:
       return ERROR_SUCCESS; }  // correct program exit.
    Did you perhaps mean EXIT_SUCCESS? You'll need stdlib.h for that.


    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by quzah View Post
    Did you perhaps mean EXIT_SUCCESS? You'll need stdlib.h for that.
    Quzah.
    My bad twice... been spending a lot of time working in Windows API lately...

    EXIT_SUCCESS or just plain old 0 ....
    Last edited by CommonTater; 09-14-2011 at 04:28 PM. Reason: 2 lines ... 3 edits... Grrrrrr....

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by CommonTater View Post
    My bad twice... been spending a lot of time working in Windows API lately...
    That explains "ERROR_SUCCESS" being an oxymoron.


    Quzah.
    Hope is the first step on the road to disappointment.

  8. #8
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by quzah View Post
    That explains "ERROR_SUCCESS" being an oxymoron.
    Quzah.
    LOL... what can I say... I didn't write the darned thing... I just get stuck using it.
    (BTW... Have I said lately just how much I hate TreeView controls??? )


    from winerror.h...
    Code:
    #define ERROR_SUCCESS  0L
    #define NO_ERROR 0L
    #define SEC_E_OK  ((HRESULT)0x00000000L)
    
    #define ERROR_INVALID_FUNCTION  1L
    #define ERROR_FILE_NOT_FOUND  2L
    #define ERROR_PATH_NOT_FOUND  3L
    #define ERROR_TOO_MANY_OPEN_FILES  4L
    #define ERROR_ACCESS_DENIED  5L
    #define ERROR_INVALID_HANDLE  6L
    #define ERROR_ARENA_TRASHED  7L
    #define ERROR_NOT_ENOUGH_MEMORY  8L
    ... and on and on....
    Last edited by CommonTater; 09-14-2011 at 04:34 PM.

  9. #9
    Registered User
    Join Date
    May 2011
    Location
    Around 8.3 light-minutes from the Sun
    Posts
    1,949
    Well, if we are going around making our own functions.....
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    char* getLine(int);
    int strCmp(const char*, const char*);
    
    int main(void) {
    	
    	char *input1, *input2;
    
    	printf("Enter a line of text:");
    	input1 = getLine(0);
    	printf("Enter another line of text:");
    	input2 = getLine(0);
    
    	if(strCmp(input1,input2)==0)
    		printf("You entered the same string");
    	else
    		printf("You entered different strings");
    
    	return 0;
    }
    char* getLine(int size){
        
    	char *string;
        int myChar;
    
        myChar= getchar();
        if(myChar=='\n' || myChar==EOF){
    		string = malloc( size + 1 );
    		string[size] = '\0';
    	}else{
            string = getLine( size + 1 );
            string[size] = myChar;
    	}
    	return string;
    }
    int strCmp(const char *string1, const char *string2){
    
    	while(*string1 || *string2){
    		if(*string1 != *string2){
    			if(*string1 > *string2)
    				return 1;
    			return -1;
    		}
    		if(*string1)
    			string1++;
    		if(*string2)
    			string2++;
    	}
    	return 0;
    }
    Last edited by AndrewHunter; 09-14-2011 at 06:28 PM. Reason: weird formatting...
    Quote Originally Posted by anduril462 View Post
    Now, please, for the love of all things good and holy, think about what you're doing! Don't just run around willy-nilly, coding like a drunk two-year-old....
    Quote Originally Posted by quzah View Post
    ..... Just don't be surprised when I say you aren't using standard C anymore, and as such,are off in your own little universe that I will completely disregard.
    Warning: Some or all of my posted code may be non-standard and as such should not be used and in no case looked at.

  10. #10
    Registered User
    Join Date
    Sep 2011
    Posts
    18
    Quote Originally Posted by anduril462 View Post
    A couple things first:
    • It's int main(void) and return an int at the end.
    • Always specify a return type and parameter list (or lack there of) for your functions explicitly. That is, mystrcmp needs an explicit "int" in front of it.
    • Either define your functions before you use them, or put a prototype at the top of the file


    The first two things on there make me think some of the tutorials/books you're using are a bit outdated, so be wary.

    As for your "eposit" issue, getchar removes the letter from the input buffer, so when you call it in the if statement you highlighted, you remove the first letter, whether it's a 'q', a 'd' or anything else. You need to call getLine first, then check if input[0] is a 'q'.
    Well what I was told was to use character scanning and scan strings one by one. It has definitely helped me realize what happens in the process of reading strings. I have learned of the scanf() function as well, but was told not to use it, the reason being it was prone to cause errors for beginner's learning C. How valid that statement is I do not know, but I've rather liked learning this process of scanning characters. Can anyone clarify as to why this is so? I probably will begin using scanf() from now on seeing how it will save me much more time.

    Also, can anyone tell me what I'm doing wrong with my array? I can't seem to find the problem.

    If anyone is interested, this is where I learn most of my C programming from http://www.eskimo.com/~scs/cclass/notes/top.html
    Last edited by edishuman; 09-14-2011 at 11:39 PM.

  11. #11
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by edishuman View Post
    Well what I was told was to use character scanning and scan strings one by one. It has definitely helped me realize what happens in the process of reading strings. I have learned of the scanf() function as well, but was told not to use it, the reason being it was prone to cause errors for beginner's learning C. How valid that statement is I do not know, but I've rather liked learning this process of scanning characters. Can anyone clarify as to why this is so? I probably will begin using scanf() from now on seeing how it will save me much more time.
    If your instructions say go char by char, then do so. But heed the last paragraph in my original reply. It tells you how to rearrange your code to avoid your "eposit" issue. If you aren't supposed to do that, look at the ungetc() function, but remember, you are only guaranteed the ability to put back 1 char.

    scanf is something like a "with great power comes great responsibility" function. It allows you a lot of flexability in getting input, but you can screw up the format string easily. It's better used for formatted data, like from a file, or for parsing strings read with fgets. One of the big complaints is how scanf handles different data types. For example, the %c modifier is the only one that actually stores a white space character (space, tab, new line, etc). The %[] modifier can store a white space character depending on what you put inside. Also, scanf is notorious for leaving the newline in the input buffer after you read a number, so many newbies read an int with %d, then wonder why their %c didn't work (hint, it grabbed the newline from when they hit enter after their int).


    Also, can anyone tell me what I'm doing wrong with my array? I can't seem to find the problem.
    I assume you mean the second problem you were having, with your command array printing garbage. Take another look at Quzah's first reply:
    Quote Originally Posted by quzah View Post
    command is not a qualified string. It's just an uninitialized array. It's pure luck that it "worked" with its size as 10.
    I added the color to draw your attention to the important parts. It's not qualified, because it's not null terminated at every step. There are no nulls in there to tell printf when to stop printing. He said it's uninitialized, so initialize it:
    Code:
    char command[20] = {0};  // set command to all nulls

    If anyone is interested, this is where I learn most of my C programming from C Programming Notes
    Not a bad site, but a bit outdated. It's meant to supplement K&R's "The C Programming Language" (which was written in the early 90s), and the site itself dates from 95-96.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Simple login/password check
    By ceevee in forum C++ Programming
    Replies: 26
    Last Post: 01-17-2005, 12:05 AM
  2. (!)Simple array exercise
    By Fizz in forum C++ Programming
    Replies: 8
    Last Post: 05-13-2004, 12:45 PM
  3. Simple check program
    By Shadow in forum C Programming
    Replies: 3
    Last Post: 06-05-2002, 06:20 PM