Function to get and return a C string

  • (3 Pages)
  • +
  • 1
  • 2
  • 3

43 Replies - 1853 Views - Last Post: 02 April 2013 - 02:56 PM Rate Topic: -----

#31 synlight  Icon User is offline

  • D.I.C Addict

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Re: Function to get and return a C string

Posted 02 April 2013 - 10:25 AM

View Postjimblumberg, on 02 April 2013 - 12:22 PM, said:

What is the purpose of the str[] variable, you never use it. Since you don't pass the size of the array to the function you should be using a const global variable for the maximum size for all of your arrays. Otherwise you will be in trouble. For instance if you pass the state[] array from your structure to this function you will allow out of bounds access to this array, which is a very bad thing.

getName();

Where are the required parameters?


Jim

Whoops. The str variable was left there from testing, when I was changing so many things around trying to get it to work. I forgot to delete it. Will fix it now.

I'll work on passing a limit.. I'm just scared I'm going to break it lol, so I was going to wait until the program was finished.
Was This Post Helpful? 0
  • +
  • -

#32 synlight  Icon User is offline

  • D.I.C Addict

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Re: Function to get and return a C string

Posted 02 April 2013 - 10:31 AM

I call getString from within the getName function.

Ugh. I was trying to be helpful, guess I wasn't very successful.

void getName()
{
	char testName[28];
	getString("Please enter the customer name:", testName);

	while(testName[0]=='\0')
		getString("Invalid customer name:", testName);
}

This post has been edited by synlight: 02 April 2013 - 10:31 AM

Was This Post Helpful? 0
  • +
  • -

#33 jimblumberg  Icon User is online

  • member icon


Reputation: 4278
  • View blog
  • Posts: 13,434
  • Joined: 25-December 09

Re: Function to get and return a C string

Posted 02 April 2013 - 10:36 AM

Then how are you returning the value of testName to the calling function so you can copy this string to your other string?


Jim
Was This Post Helpful? 0
  • +
  • -

#34 synlight  Icon User is offline

  • D.I.C Addict

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Re: Function to get and return a C string

Posted 02 April 2013 - 10:37 AM

with strcpy

//NAME
		getName();
		strcpy(table[pos].name, buffer);

Was This Post Helpful? 0
  • +
  • -

#35 jimblumberg  Icon User is online

  • member icon


Reputation: 4278
  • View blog
  • Posts: 13,434
  • Joined: 25-December 09

Re: Function to get and return a C string

Posted 02 April 2013 - 10:40 AM

But where is buffer coming from?

Jim
Was This Post Helpful? 0
  • +
  • -

#36 synlight  Icon User is offline

  • D.I.C Addict

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Re: Function to get and return a C string

Posted 02 April 2013 - 10:45 AM

Jim! Why are you picking on me?

My buffer is declared in main. I use it all over my program to get input.

char buffer[40];

Was This Post Helpful? 0
  • +
  • -

#37 jimblumberg  Icon User is online

  • member icon


Reputation: 4278
  • View blog
  • Posts: 13,434
  • Joined: 25-December 09

Re: Function to get and return a C string

Posted 02 April 2013 - 10:51 AM

Show your entire program. I don't think buffer is a valid value! After all you're not returning anything from getName().

Jim
Was This Post Helpful? 0
  • +
  • -

#38 synlight  Icon User is offline

  • D.I.C Addict

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Re: Function to get and return a C string

Posted 02 April 2013 - 11:12 AM

Oookay.. you asked for it. I know I'm far from perfect.. but I try really hard.

The way I understand it.. I am passing buffer, and after validating my input, I put it into the buffer and then into my structure.

/***************************************************
* NAME: Syn                               *  
* PROG: A4                          *
* PURP: data entry/verification* 
****************************************************/

# include <cstdio>
# include <cstring>
# include <string>
# include <windows.h>
# include <stdio.h>
# include <float.h>

using namespace::std;

struct dueDate
	{
		int month;
		int day;
		int year;
	};

struct record
	{
		int custID;
		char name[28];
		char state[3];
		char discCode;
		double balanceDue;
		dueDate date;
	};

static struct state
	{
		char abbrev[3];
	};
//PROTOTYPES

void getString(char *prompt, char *buffer);


int getInt(char*);
double getDouble(char*);
char getChar(char*);
void setWindow(int, int);
void list(struct record *table, int);

int getCustID(char*);
void getName();
void getState(char*);
char getCode();
double getBalance();
void getDate(char*);

bool testInt(char*);
bool testDouble(char*, double);
bool validState(char*);
bool testCode(char*);
bool validDate(int, int, int);

/**************************
* MAIN - Process  *
***************************/

int main()
{

	setWindow(100,75);
	char buffer[40];
	int quit = 0;
	int pos = 0;
	int testID = 0;
	int length = 40;
	char testName[40];
	char testState[3];
	char testCode;
	double testBalance = 0.00;
	char testDate[40];
	dueDate date; 
	record table[50];
	FILE *myFile;
	
	

	quit = getInt("Add record? 1 = YES 2 = QUIT");

	while (quit != 2)
	{
		//test selection
		if(quit!=1)
				quit = getInt("Invalid selection. Try again. 1 = ADD RECORD 2 = QUIT");

		//CUSTOMER ID
		
		table[pos].custID = getCustID(buffer);
		
		//NAME
		getName();
		strcpy(table[pos].name, buffer);

		//DISCOUNT CODE
		table[pos].discCode = getCode(); 

		//BALANCE DUE
		table[pos].balanceDue = getBalance();
	
		//STATE
		getState(buffer);
		strcpy(table[pos].state, buffer);

		//DATE
		getString("Please enter the due date as XX/XX/XXXX", buffer);
		strcpy(testDate, buffer);

		validState(buffer);

		pos++;
			
		quit = getInt("Add record? 1 = YES 2 = QUIT"); 
	}//END PROCESS WHILE

	myFile = fopen("myFile.txt", "w");
	for(int x = 0; x < pos; x++)
	{
		fprintf(myFile, "%i\n", table[x].custID);
	}

	fclose(myFile);
	list(table, pos);

	printf("Press any key to exit...");
	gets(buffer);
}//END MAIN


/***********************************************
* Gets and returns custID, validates ID <= 998 *
************************************************/
int getCustID(char buffer[])
{
	
	int ID = 0;
	bool isInt = false;
	getString("\nEnter the customerID:", buffer);

	isInt = testInt(buffer);

	if (isInt == true)
		ID = atoi(buffer);

	while(ID > 998)
	{
		getString("\nInvalid customer ID. Enter the customerID:", buffer);
		isInt = testInt(buffer);
		if (isInt == true)
			ID = atoi(buffer);
	}
	
	return ID;
}

/***********************************************
* Gets and returns name *
************************************************/
void getName()
{
	char testName[28];
	getString("Please enter the customer name:", testName);

	while(testName[0]=='\0')
		getString("Invalid customer name:", testName);
}


/***********************************************
* Gets and returns balance *
************************************************/
double getBalance()
{
	char testBal[40];
	double balance = 0.00;
	char test = '.';
	int accum = 0;
	bool floatTest = false;
	getString("\nPlease enter the balance due:", testBal);

	if(floatTest == true)
	{
		for(int x = 0; x < strlen(testBal); x++)
		{
			if(testBal[x] == '.')
				accum++;
		}

		if(accum>1)
			getString("\nInvalid balance due, please try again:", testBal);
	}

	return balance;

}//END GETBALANCE

/***********************************************
* Gets and returns state *
************************************************/
void getState(char buffer[])
{
	bool goodState = false;
	getString("Please enter the state as a 2 character abbreviation:", buffer);
	goodState = validState(buffer);
	while(!goodState)
	{
		getString("Invalid state, please try again:", buffer);
		goodState = validState(buffer);
	}
	 
}//END GETSTATE

/***********************************************************
* Gets and returns an Integer, validate number is numeric  *
************************************************************/
int getInt(char prompt[])
{
	int number = 0;
	char buffer[40];
	bool isInt = true;
	printf("\n%s",prompt);
	fgets(buffer,40,stdin);
	
	isInt= testInt(buffer);

	if (isInt == true)
		number = atoi(buffer);

	//else
	while(isInt == false)
	{
		printf("Entry must be numeric. Please try again.");
		fgets(buffer,40,stdin);
		isInt= testInt(buffer);
		number = atoi(buffer);
	}

	return number;	
}//END getInt

/*********************************
* Test string as Integer  *
*********************************/
bool testInt(char* buffer)
{
	bool isInt = true;

    for(int x = 0; x < strlen(buffer); x++)
	{
      if(isdigit(buffer[x]))
	  {
		break;
	  }
	  else
		isInt = false;
    }//ENDFOR
  return isInt;
}//END TESTINT


/*********************************
* Test string as Double  *
*********************************/
bool testFloat(char* buffer)
{
	bool isFloat = true;

    for(int x = 0; x < strlen(buffer); x++)
	{
      if(_isnan(buffer[x]))
	  {
		break;
	  }
	  else
		isFloat= false;
    }//ENDFOR

  return isFloat;
}//END TESTINT

/*********************************
* Test state abbreviation  *
*********************************/	
bool validState(char buffer[])
{
	
	static state states[50];
	bool validState = false;
	char buff[20];

	//if(strcmp("AK",states[0].abbrev))
	if(states[0].abbrev[0] == '\0')
	{
		FILE *myFile;
		myFile = fopen("states.dat","r");

		if(myFile!=NULL)
			for(int x = 0; x<50;x++)
			{
				fgets(buff,20,myFile);
				fgets(buff,20,myFile);
				strcpy(states[x].abbrev,buff);
				printf("%s",states[x].abbrev);
			}
		fclose(myFile);
	}

	toupper(buffer[0]);
	toupper(buffer[1]);

	for(int x=0;x<50;x++)
	{
		if(strcmp(buffer,states[x].abbrev))
		{
			validState = true;
			break;
		}
	}	
	

	return validState;
}//END TESTSTATE

/*********************************
* Get discount code  *
*********************************/
char getCode()
{
   
    char testCode;
	bool validCode = false;
	testCode = getChar("\nPlease enter the discount code:");

	

	if (testCode == '\n')
		validCode = true;

	while(!validCode)
	{
		testCode = toupper(testCode);

		if(testCode =='A' || testCode == 'B' || testCode == 'C')
			validCode = true;
		else
			testCode = getChar("\nInvalid discount code. Please try again:");
	}//ENDWHILE
		

    return testCode;
}//END GETCODE


/***********************************************
* Get Due date *
************************************************/
void getDate(char buffer[])
{

	char month[3];
	char day[3];
	char year[5];
	char *pnt;

	getString("Please enter the due date as XX/XX/XXXX", buffer);

	if(buffer[2] != '/' || buffer[5] != '/')
		getString("Invalid date format. Please try again as XX/XX/XXXX", buffer);

	pnt = strtok(buffer, "/");

	while(pnt!=NULL)
	{

	}

	printf("Date:%s%s%s", month, day, year);

}//END GETDATE

/***********************************************
* Test Date
************************************************/
bool validDate(int month, int day, int year)
{
	bool validDate = false;
	int numDays = 0;
	bool monthFlag = false;
	bool dayFlag = false;
	bool yearFlag = false;

	if(month > 0 && month < 13)
	{
		monthFlag = true;

		if(month == 4 || month == 9 || month == 6 || month == 11)
			numDays = 30;

		else if (month == 2)
		{
			if (year % 4 == 0)
			{
				if(year % 100 > 0)
				{
					numDays = 29;
				}
				else 
					numDays = 29;
			}
			else
				numDays = 28;
		}//END LEAPYEAR
		else 
		numDays = 31;
	}//END MONTH TEST	
	else
		printf("You have entered an invalid month");

	if(day <= numDays || day >= numDays)
		printf("You have entered an invalid day.");
	else
		dayFlag = true;

	if(year > 2013)
		printf("You have entered an invalid year.");
	else
		yearFlag = true;

	if(monthFlag == true && dayFlag == true && yearFlag == true)
		validDate == true;


	return validDate;
}//END VALIDDATE

/**************************
* LIST - display file contents in arrays *
***************************/
void list(record table[], int pos)
{
	printf("CustID	     Name	    State   Disc Code	Balance		Due Date\n");
	for(int x = 0; x < pos;x++)
	{
		printf("%5i",table[x].custID);
		printf("%20s",table[x].name);
		printf("%6s",table[x].state);
		printf("%8c",table[x].discCode);
		printf("%16.2f",table[x].balanceDue);
		printf("%18s\n",table[x].date);
	}
	printf("\n\n");

}//END LIST
/*********************************
* Gets and returns a Double  *
*********************************/	
double getDouble(char prompt[])
{
	double number = 0.00;
	char buffer[40];
	printf("\n%s",prompt);
	fgets(buffer,40,stdin);
	number = atof(buffer);

	return number;

}//END getDouble

/*********************************
* Gets and returns a String  *
*********************************/
void getString(char prompt[], char buffer[])
{
	printf("\n%s",prompt);
	fgets(buffer,40,stdin);

}//END GETSTRING


/*********************************
* Gets and returns a Char  *
*********************************/
char getChar(char prompt[])
{

	char code = ' ';
	printf("\n%s",prompt);
	code = getchar();
	printf("code='%d'\n",int( code));

	return code;
}//END GETCHAR

/***********************************
* Make the console window sizeable *
************************************/
void setWindow(int Width, int Height)
    {
    _COORD coord;
    coord.X = Width;
    coord.Y = Height;

    _SMALL_RECT Rect;
    Rect.Top = 0;
    Rect.Left = 0;
    Rect.Bottom = Height - 1;
    Rect.Right = Width - 1;

    HANDLE Handle = GetStdHandle(STD_OUTPUT_HANDLE);      // Get Handle
    SetConsoleScreenBufferSize(Handle, coord);            // Set Buffer Size
    SetConsoleWindowInfo(Handle, TRUE, &Rect);            // Set Window Size
    }



EDIT: This program is far from working properly. I doubt my ability to get it running and submitted my midnight tonight, when it's due. I've spent 4 days on it so far, which is really sad.

This post has been edited by synlight: 02 April 2013 - 11:23 AM

Was This Post Helpful? 0
  • +
  • -

#39 jimblumberg  Icon User is online

  • member icon


Reputation: 4278
  • View blog
  • Posts: 13,434
  • Joined: 25-December 09

Re: Function to get and return a C string

Posted 02 April 2013 - 11:27 AM

So, as I suspected your buffer is actually not valid for the name, it contains the ID number.

		table[pos].custID = getCustID(buffer);

		//NAME
		getName();
		strcpy(table[pos].name, buffer); // Contains CustID not the name.


Also since your instructor is an idiot all of your character strings should have the same size, to avoid possible buffer overruns. So I recommend you use something like 100 for all your array sizes.

const int ARRAY_SIZE = 100; 


Then use this a the size of ever character array.

struct record
	{
		int custID;
		char name[ARRAY_SIZE];
		char state[ARRAY_SIZE];
		char discCode;
		double balanceDue;
		dueDate date;
	};




Jim
Was This Post Helpful? 0
  • +
  • -

#40 synlight  Icon User is offline

  • D.I.C Addict

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Re: Function to get and return a C string

Posted 02 April 2013 - 11:31 AM

When I call getName, it doesn't overwrite the buffer with the new string?

When I tested it with printf it worked. I know that's not always a good indicator that I'm doing things correctly though.
Was This Post Helpful? 0
  • +
  • -

#41 jimblumberg  Icon User is online

  • member icon


Reputation: 4278
  • View blog
  • Posts: 13,434
  • Joined: 25-December 09

Re: Function to get and return a C string

Posted 02 April 2013 - 11:34 AM

How does getName() even know about that variable? You're not passing any variables into this function. I myself would just get rid of getName() and just call getString() with the proper arguments.

Jim
Was This Post Helpful? 0
  • +
  • -

#42 synlight  Icon User is offline

  • D.I.C Addict

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Re: Function to get and return a C string

Posted 02 April 2013 - 11:39 AM

I have to test the name for nulls, in it's own function, before I can put it into my struct.

I'm so confused. I wish I had time to just start over from scratch and make the whole program make more sense. I have a weird mashup of the program I started out with, and the program he wants, because I didn't understand the problem statement fully until last night.
Was This Post Helpful? 0
  • +
  • -

#43 jimblumberg  Icon User is online

  • member icon


Reputation: 4278
  • View blog
  • Posts: 13,434
  • Joined: 25-December 09

Re: Function to get and return a C string

Posted 02 April 2013 - 12:10 PM

Edit: I'm having problems posting to this thread you can try to view the answer here, post number 38.

Spoiler


Jim

This post has been edited by jimblumberg: 02 April 2013 - 12:21 PM

Was This Post Helpful? 2
  • +
  • -

#44 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1431
  • View blog
  • Posts: 4,966
  • Joined: 19-February 09

Re: Function to get and return a C string

Posted 02 April 2013 - 02:56 PM

View Postsynlight, on 02 April 2013 - 06:39 PM, said:

I have to test the name for nulls, in it's own function, before I can put it into my struct.


What does test for nulls mean?

The string could be a null string ie length of zero.

getString with fgets leaves the newline in the string, should you not remove it?
Was This Post Helpful? 0
  • +
  • -

  • (3 Pages)
  • +
  • 1
  • 2
  • 3