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*drinkN ame[45];************** *******
****char*manufa cturer[25];**********
****float*purch asePrice;
} DRINK;
void option1(DRINK drinkArray[], DRINK drinkRec)
{
****FILE**fp*=* fopen("products .txt",*"r");
****char*line[255]*=*"";
****int*count*= *0;
****printf("\nR ead*records*fro m*file\n");
****printf("=== =============== ====\n\n");
****if(fp)
****{
********while(( fgets(line,*siz eof(line),*fp)* !=*NULL))
********{
************ssc anf(line,*"%d*% 44s*%24s*%f\n", *&drinkRec.stoc kCode,
************dri nkRec.drinkName ,**drinkRec.man ufacturer,
************&dr inkRec.purchase Price);
************if( addDrinkArray(* drinkArray,*dri nkRec))
*************** *++count;
************els e
************{
*************** *printf("Array* is*full:*");
*************** *break;
************}
********}
****fclose(fp);
****}
****else
********printf( "Error*opening* file");
****printf("%d* records*succsef ffully*added\n" ,*count);
}
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 getValidPurchas ePrice(float* purchasePrice, int bypass)
{
****char*line[255];
****char**test;
****int*retval* =*1;
****while(1)
****{
********printf( "Please*enter*t he*purchase*pri ce*");
********fgets(l ine,*sizeof(lin e),*stdin);
*********purcha sePrice*=*strto d(line,*&test);
********if(issp ace(*test)*&&*l ine[0]*!=*'\n')
********{
*************br eak;
********}
********else*if (line[0]*==*'\n'*&&*byp ass*!=*0)
********{
************ret val*=*0;
************bre ak;
********}
********line[strlen(line)*-*1]*=*'\0';
********printf( "%s*is*not*a*va lid*purchase*pr ice\n",*line);
****}
****return*retv al;
}
Thanks in advance
Sean Kemplay 4 1615
"S Kemplay" <sk******@dingl ey.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(li ne, 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.stock Code, drinkRec.drinkN ame, drinkRec.manufa cturer, &drinkRec.purch asePrice);
sscanf() returns the number of items successfully converted. Check the
return value and bale if the record is malformed. if(addDrinkArra y( 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(cha r *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 getValidPurchas ePrice(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(*tes t) && 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(cons t 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.
"S Kemplay" <sk******@dingl ey.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(li ne, 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.stock Code, drinkRec.drinkN ame, drinkRec.manufa cturer, &drinkRec.purch asePrice);
sscanf() returns the number of items successfully converted. Check the
return value and bale if the record is malformed. if(addDrinkArra y( 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(cha r *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 getValidPurchas ePrice(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(*tes t) && 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(cons t 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.
Thankyou for your suggestions Malcolm, as well as being more failsafe, my
functions are a lot more portable now.
Cheers
Sean
Thankyou for your suggestions Malcolm, as well as being more failsafe, my
functions are a lot more portable now.
Cheers
Sean This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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 was a little amazed
at this and wondered if I'd somehow misunderstood the situation.
I'm pleased to find that Joel Spolsky shared my amazement and offered
some criticism of PHP on these grounds: "When I discovered that the
popular web development...
|
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";
char search = '?';
char* replace = "***";
char* result = search_and_replace(source,search,replace);
|
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 operations I need to
convert the string to a 32 bit integer, carry out the arithmetic operation,
then convert it back to a string before pushing it back onto the stack.
This can happen millions of times per second so it is essential that I have...
|
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 - 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:
|
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?
| |
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 my purposes. As
this code was posted long time ago (November 1998) I would like to ask
if the principles used in this code are still valid in the "modern"
Python and if/how it can be improved (revrited) using futures of
current version of...
|
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 page content so it's just an optical
background.
During the process of loading the page on the client, pages which implement
the above mentioned masterpage are build very excursive. That looks
|
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 = open('questions.txt')
numberQuestionDictionary = {}
for line in questionFile.readlines():
if not line:
continue
line = line.strip()
if len(line) == 0:
|
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 elements are made. I was
thinking of using a function, that kept an index, to selectively iterate
over unsorted elements. But I am unable to think of a way to do it.
Any ideas to improve the routine and get a better grade?
Thanks to all.
|
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 to work out how to start on a
solution.
I have of course used a varienty of componets, mostly radio buttons
with "button" appearence.
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
| |
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
| |
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |