473,385 Members | 1,796 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

How can I improve these functions?

Hi all,

I am after any pointers you may have to improve these two functions.

They both work but are part of an assignment - I am looking for feedback.

The first one reads records from a file - the teacher won't allow a
delimeted file he wants spaces between words joined with an underscore.

The records are read into an array of structs:

typedef struct drink
{
int*stockCode;**************************
****char*drinkName[45];*********************
****char*manufacturer[25];**********
****float*purchasePrice;
} DRINK;

void option1(DRINK drinkArray[], DRINK drinkRec)
{
****FILE**fp*=*fopen("products.txt",*"r");
****char*line[255]*=*"";
****int*count*=*0;
****printf("\nRead*records*from*file\n");
****printf("======================\n\n");
****if(fp)
****{
********while((fgets(line,*sizeof(line),*fp)*!=*NU LL))
********{
************sscanf(line,*"%d*%44s*%24s*%f\n",*&dri nkRec.stockCode,
************drinkRec.drinkName,**drinkRec.manufact urer,
************&drinkRec.purchasePrice);
************if(addDrinkArray(*drinkArray,*drinkRec ))
****************++count;
************else
************{
****************printf("Array*is*full:*");
****************break;
************}
********}
****fclose(fp);
****}
****else
********printf("Error*opening*file");

****printf("%d*records*succsefffully*added\n",*cou nt);
}

The second function is to validate user input - I need a float for
purchasePrice. I have a similar one for an int.

I want to be able to accept a newline as valid when this function is used to
get input to update a record ie "Enter a purchase price or press enter to
leave unchanged" so I have set a flag. If the flag is true, the return
signals whether a newline was entered or not.

int getValidPurchasePrice(float* purchasePrice, int bypass)
{
****char*line[255];
****char**test;
****int*retval*=*1;
****while(1)
****{
********printf("Please*enter*the*purchase*price*") ;
********fgets(line,*sizeof(line),*stdin);
*********purchasePrice*=*strtod(line,*&test);
********if(isspace(*test)*&&*line[0]*!=*'\n')
********{
*************break;
********}
********else*if(line[0]*==*'\n'*&&*bypass*!=*0)
********{
************retval*=*0;
************break;
********}
********line[strlen(line)*-*1]*=*'\0';
********printf("%s*is*not*a*valid*purchase*price\n ",*line);
****}
****return*retval;
}
Thanks in advance

Sean Kemplay
Nov 14 '05 #1
4 1568

"S Kemplay" <sk******@dingley.net> wrote in message

I am after any pointers you may have to improve these two
functions.

typedef struct drink
{
int stockCode;
char drinkName[45];
char manufacturer[25];
float purchasePrice;
} DRINK;
/*
First I'll give you local improvements, then I'll explain how to redesign.
*/ void option1(DRINK drinkArray[], DRINK drinkRec)
{
FILE* fp = fopen("products.txt", "r");
char line[255] = "";
int count = 0;
printf("\nRead records from file\n");
printf("======================\n\n");
if(fp)
{
while((fgets(line, sizeof(line), fp) != NULL)) /*
You want to check that a full line was read by looking for the newline.
*/ {
sscanf(line, "%d %44s %24s %f\n", &drinkRec.stockCode,
drinkRec.drinkName, drinkRec.manufacturer,
&drinkRec.purchasePrice);
sscanf() returns the number of items successfully converted. Check the
return value and bale if the record is malformed.
if(addDrinkArray( drinkArray, drinkRec))
++count;
else
{
printf("Array is full: "); /*
This is a bit lame. You need to be able to read records until the computer
runs out of memory.
*/ break;
}
}
fclose(fp);
}
else
printf("Error opening file"); /*
You might consider printing errors to stderr.
*/
printf("%d records succsefffully added\n", count);
}
Why not rewrite the function

/*
Returns an allocated array of N drinks read from the file.
*/
DRINK *readdrinks(char *fname, int *N)
{
}
Also, you could get rid of all the output to printf() and put it somewhere
else, so the function is more portable.
The second function is to validate user input - I need a float for
purchasePrice. I have a similar one for an int.

I want to be able to accept a newline as valid when this function is used to get input to update a record ie "Enter a purchase price or press enter to
leave unchanged" so I have set a flag. If the flag is true, the return
signals whether a newline was entered or not.

int getValidPurchasePrice(float* purchasePrice, int bypass)
{
char line[255];
char* test;
int retval = 1;
while(1)
{
printf("Please enter the purchase price ");
fgets(line, sizeof(line), stdin);
*purchasePrice = strtod(line, &test);
if(isspace(*test) && line[0] != '\n')
{
break;
}
else if(line[0] == '\n' && bypass != 0)
{
retval = 0;
break;
}
line[strlen(line) - 1] = '\0';
printf("%s is not a valid purchase price\n", line);
}
return retval;
}

Write the function

int validmoney(const char *str, double minprice, double maxprice)
{
Call strtod. Check for garbage following what you read. This tells
you you have a valid floating-point number.
Checking for min price and max price is trivial (min might be 1 cent, max
can be DBL_MAX or you might want to sanity check).
However 12 and 12.34 are valid, 12.3 and 12.345 are not. You need to use
strchr() to seach for the decimal point and, if it exists, count the digits
(using isdigit). If there are two then you are OK, if not then reject it.
}

Input can also be invlaid if fgets() fails to read a line. keep this
separate from your validmoney() function.
Nov 14 '05 #2

"S Kemplay" <sk******@dingley.net> wrote in message

I am after any pointers you may have to improve these two
functions.

typedef struct drink
{
int stockCode;
char drinkName[45];
char manufacturer[25];
float purchasePrice;
} DRINK;
/*
First I'll give you local improvements, then I'll explain how to redesign.
*/ void option1(DRINK drinkArray[], DRINK drinkRec)
{
FILE* fp = fopen("products.txt", "r");
char line[255] = "";
int count = 0;
printf("\nRead records from file\n");
printf("======================\n\n");
if(fp)
{
while((fgets(line, sizeof(line), fp) != NULL)) /*
You want to check that a full line was read by looking for the newline.
*/ {
sscanf(line, "%d %44s %24s %f\n", &drinkRec.stockCode,
drinkRec.drinkName, drinkRec.manufacturer,
&drinkRec.purchasePrice);
sscanf() returns the number of items successfully converted. Check the
return value and bale if the record is malformed.
if(addDrinkArray( drinkArray, drinkRec))
++count;
else
{
printf("Array is full: "); /*
This is a bit lame. You need to be able to read records until the computer
runs out of memory.
*/ break;
}
}
fclose(fp);
}
else
printf("Error opening file"); /*
You might consider printing errors to stderr.
*/
printf("%d records succsefffully added\n", count);
}
Why not rewrite the function

/*
Returns an allocated array of N drinks read from the file.
*/
DRINK *readdrinks(char *fname, int *N)
{
}
Also, you could get rid of all the output to printf() and put it somewhere
else, so the function is more portable.
The second function is to validate user input - I need a float for
purchasePrice. I have a similar one for an int.

I want to be able to accept a newline as valid when this function is used to get input to update a record ie "Enter a purchase price or press enter to
leave unchanged" so I have set a flag. If the flag is true, the return
signals whether a newline was entered or not.

int getValidPurchasePrice(float* purchasePrice, int bypass)
{
char line[255];
char* test;
int retval = 1;
while(1)
{
printf("Please enter the purchase price ");
fgets(line, sizeof(line), stdin);
*purchasePrice = strtod(line, &test);
if(isspace(*test) && line[0] != '\n')
{
break;
}
else if(line[0] == '\n' && bypass != 0)
{
retval = 0;
break;
}
line[strlen(line) - 1] = '\0';
printf("%s is not a valid purchase price\n", line);
}
return retval;
}

Write the function

int validmoney(const char *str, double minprice, double maxprice)
{
Call strtod. Check for garbage following what you read. This tells
you you have a valid floating-point number.
Checking for min price and max price is trivial (min might be 1 cent, max
can be DBL_MAX or you might want to sanity check).
However 12 and 12.34 are valid, 12.3 and 12.345 are not. You need to use
strchr() to seach for the decimal point and, if it exists, count the digits
(using isdigit). If there are two then you are OK, if not then reject it.
}

Input can also be invlaid if fgets() fails to read a line. keep this
separate from your validmoney() function.
Nov 14 '05 #3
Thankyou for your suggestions Malcolm, as well as being more failsafe, my
functions are a lot more portable now.

Cheers

Sean
Nov 14 '05 #4
Thankyou for your suggestions Malcolm, as well as being more failsafe, my
functions are a lot more portable now.

Cheers

Sean
Nov 14 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: lkrubner | last post by:
Last year I asked a bunch of questions about character encoding on this newsgroup. All the answers came down to using ord() in creative ways to try to make guesses about multi-byte characters. I...
10
by: pembed2003 | last post by:
Hi all, I asked this question in the C group but no one seems to be interested in answering it. :-( Basically, I wrote a search and replace function so I can do: char source = "abcd?1234?x";...
17
by: Sean Kenwrick | last post by:
I am writing a byte-code interpreter/emulator for a language that exclusively uses strings for variables (i.e all variables are pushed onto the stack as strings). Therefore for arithmetic...
0
by: S Kemplay | last post by:
Hi all, I am after any pointers you may have to improve these two functions. They both work but are part of an assignment - I am looking for feedback. The first one reads records from a file...
9
by: Peng Jian | last post by:
I have a function that is called very very often. Can I improve its efficiency by declaring its local variables to be static?
41
by: Petr Jakes | last post by:
Hello, I am trying to study/understand OOP principles using Python. I have found following code http://tinyurl.com/a4zkn about FSM (finite state machine) on this list, which looks quite useful for...
5
by: Cenk Genisol | last post by:
Hi NG, I am relatively new to Web developement and have some questions to you. I've got a Masterpage where some graphics are embedded by CSS. They format the borders of tables, which store...
1
by: lostbuttrying | last post by:
Trying to set up a file for questions and answers. Doesn't seem to be working properly. Can anyone see where I can improve my functions? This is what I have so far: questionFile =...
75
by: At_sea_with_C | last post by:
Hello all, I have written an ascending sort routine for floats. This seems to do the job, but for elements over 10,000, it gets awfully slow. A lot of useless comparisions with previously sorted...
11
by: Peted | last post by:
Im using c# 2005 express edition Ive pretty much finished an winforms application and i need to significantly improve the visual appeal of the interface. Im totaly stuck on this and cant seem...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.