1. Homepage
  2. Programming
  3. PA1_ A General Mass Unit Converter

PA1_ A General Mass Unit Converter

Engage in a Conversation
Boston CollegeA General Mass Unit ConverterC

PA1: A General Mass Unit Converter CourseNana.COM

Due Friday by 11:59pm Points 100 Submitting a file upload File Types c CourseNana.COM

Overview CourseNana.COM

In this project, you will develop a command-line tool to convert a quantity of mass in one unit type to the equivalent quantity in some other unit type, where the input and output unit types are chosen from among six possibilities, three in the metric system (grams, kilograms, metric tonnes) and three in the US customary system (ounces, pounds, and tons). The user enters a base-10 number (with optional decimal point and fractional part), an abbreviation of a unit type for the input unit, and another for the output unit. The program then prints an equation showing the input on the left and the equivalent value and unit after conversion on the right. The program accepts input and prints output repeatedly until the user enters a non-numeric character as a signal to quit. CourseNana.COM

Your source code will consist of a single file called pa1.c. When you test build your program, use pa1 as the name of your target executable. CourseNana.COM

High-Level Plan CourseNana.COM

Instead of explicitly programming every possible pairwise conversion from one unit type to another, we will first convert any input of any metric unit type to kilograms (kg) and any US customary input
to pounds (
lb). Then, if the desired output unit type is in the opposite system, we convert kilograms to pounds or pounds to kilograms, as the case may be, using a single conversion factor, by multiplication or CourseNana.COM

division as needed. Finally, we convert the result of that stage to the desired output unit, if any conversion is necessary. CourseNana.COM

Thus the representation of the input mass as either kilograms or pounds serves as an intermediate representation, which is then converted to the intermediate representation of the opposite system if necessary, and only then — again, ifnecessary — converted back out to the desired unit within the target system. This simplification of many pairwise transformations into an initial transformation to an intermediate representation and then another transformation back out to the desired target is an important and widely-used design pattern in many areas of software, making complex problems more tractable. CourseNana.COM

We shall call kilograms and pounts the two reference units because of their special, central role in conversion. CourseNana.COM

Symbolic Constants, Global Variables, and Type CourseNana.COM

Definitions CourseNana.COM

Define a symbolic constant LB_TO_KG to represent the value by which to multiply a quantity in pounds to get the corresponding quantity in kilograms. To convert kilgrams to pounds, you would divide the input value by this constant. Please use the value 0.45359237 as this conversion factor. CourseNana.COM

The function to do most of the work will be called convert, and it will return a double, the converted value. The user will enter, on each iteration, a numeric value (to be stored as a double), an input unit string, and an output unit string. But, throughout your logic, you will not use strings. Instead, you will use enumerators to refer to the various units. This will spare you the need to keep comparing strings, which is less efficient at a low level than comparing numbers — and recall that an enumerator is simpley a single number from the machine's point of view. So your first job is to translate the input and output strings to the corresponding units. You will thus need to define an enumeration type for the units, with the three metric units coming first, from smallest to greatest, and then the US customary units, ending with UNSUPPORTED to serve as an error code for an unsupported unit that the user may have entered. CourseNana.COM

The enumeration type should be called enum Unit and should also be aliased with a typedef to the simple name Unit. Remember to make every enumerator within this enumeration type have a name in ALL CAPS, following the convention for enumeration types and symbolic constants. CourseNana.COM

Other items to be placed near the top of the file will come up as needed in the descriptions below. CourseNana.COM

Program Structure and Flow CourseNana.COM

In main, you will print instructions to the user (see the sample session above), and then, in a loop, you will call scanf (https://www.tutorialspoint.com/c_standard_library/c_function_scanf.htm) to capture a floating-point number (of type double) and two strings, for the value, input unit string, and output unit string, respectively. (The use of scanf to capture strings from the user is notoriously unsafe, because the user may enter to much text to store in the memory buffer set aside for it, but we will learn safer techniques later.) scanf takes as arguments a format string, somewhat similar to the one used for printf, which tells it what type it should convert each successive token into, followed by the corresponding addresses in memory into which to store each of those converted values. scanf returns, as an int, the number of tokens that it has successfully scanned — that is, converted from character sequences (such as numerals) to the values whose types are specified in the format string (such as numbers of type double). Therefore, when the user enters any non-numeric character, such as "q," as the first token, scanf will immediately return 0, which counts as "false" in the loop condition, which terminates the loop and the program. All this makes it possible to put the call to scanf inside the parentheses of the while-loop header as the conditional expression. CourseNana.COM

The second and following parameters of scanf are addresses (pointers). Each variable holding an address corresponds to another conversion specifier in the format string. So above the loop, you need to declare variables of the correct types. The declarations have the effect of setting aside the necessary chunks of memory on the stack. The numeric input can be declared simply as a variable of type double, but the two input strings must be declared as arrays of type char. (Why?) For these declarations, you must stipulate a size, so you should also define, up on top right after your preprocessor definition
of
LB_TO_KG, a constant MAX_UNIT_STRING_LENGTH and set its value to 256 (far longer than any expected unit string). The extra space helps to avoid the simplest kinds of errors or attacks caused by the user entering too long a string. Use that symbolic constant as the length of your two array variables — input_unit and output_unit. CourseNana.COM

After capturing the user's input within each iteration of the scanf loop, main calls convert to get the converted value, checks it for a possible error (explained below), and then prints it out, as shown in the sample above. CourseNana.COM

The convert function takes the value and the two unit strings as input parameters and returns the converted value as a double. The unit string parameters should be marked const, but we can use the value parameter as a local variable to hold intermediate stages as we convert, so it should not be marked const. Here is the high-level logic for convert: CourseNana.COM

Convert the input and output unit strings to Unit enumerators. To do so, convert should create and use a helper function, unit_string_to_unit, which takes a unit string and returns a Unit enumerator. CourseNana.COM

Remember: either define this function above convert in the file or provide a forward declaration near the top of the file so that the compiler can check types correctly when it arrives at the call
to
unit_string_to_unit within convert. CourseNana.COM

Define, near the top of the file (but below the typedef statements), a global const variable array of strings: const char * const unit_strings[]. Initialize this constant (variable) to the sequence of string literals corresponding to the unit strings that the user may enter, in the same order as the enumerators representing the units. (There is no "unsupported" string, so the number of strings is one fewer than the number of enumerators.) CourseNana.COM

This way, in unit_string_to_unit, you simply iterate over unit_strings, using strcmp (declared in header string.h) to find a possible match. (Be sure to look up strcmp (https://www.tutorialspoint.com/c_standard_library/c_function_strcmp.htm) if you are unfamliar with it to make sure that you understand how it works.) Once you hit the index of a matching string, return that index (an int) immediately, cast (converted explicitly) as a Unit (https://www.tutorialspoint.com/cprogramming/c_type_casting.htm) . This works because enumerators are integers, though they have their own types. Returning "early" this way breaks out of the loop and terminates function execution. If you finish the loop and still have not found a match, return UNSUPPORTED to represent an unsupported unit string. CourseNana.COM

When you iterate over the elements of unit_strings, you need an upper bound for the iteration variable in your for-loop. Please DO NOT JUST USE A BARE NUMBER for this. Instead,
define
another global constant, const int num_unit_strings, and set its value to be the number of elements in unit_strings — not according to your own count, but according to the compiler. To make the compiler count for you, take the total number of bytes in the unit_strings array and divide it by the number of bytes in each element of the array. Use the sizeof operator for these values: sizeof(unit_strings) / sizeof(unit_strings[0]). This way, if you should ever wish to change the number of elements in the array, you would not have to remember to change bare numbers in your code. In the for-loop, use num_unit_strings to bound your iteration. This is a general principle of good programming — avoid bare numbers unless their meanings are totally obvious — e.g., the 0 in the expression unit_strings[0] to mean the first element. CourseNana.COM

If the resulting Unit is UNSUPPORTED, that is an error: the user must have entered some unit string that we do not support. Signal this, not by printing an error message from convert, but simply by returning a special value of type double that we will use, uniquely, to mean "error" in the present context: not a number, or NaN, declared in the math.h header as the symbolic constant NAN. CourseNana.COM

In main, we will detect the special case of a NAN return value and handle it as an error without breaking out of the scanf loop.
Now use the input and output units (of type
Unit) to follow the logic represented in the diagram above: CourseNana.COM

Convert the input value to the reference unit for the input unit system — kilograms for any metric unit and pounds for any US customary unit. CourseNana.COM

To make this easy, define another global constant array (variable), factors, of type double, with the conversion factors by which you multiply a value to get the value in its corresponding CourseNana.COM

reference unit. The entries in this array should follow the order of the Unit enumeration type, so that, for instance, the first entry in this array, the number by which to multiply grams to get kilograms, is 0.001, since a gram is a thousandth of a kilogram. Of course, the conversion factors for kilograms and pounds will both be 1.0. We can then use the Unit value (implicitly converted to int — no need for a cast) as an index into the factors array, again taking advantage of the identity or convertibility of enumerators with integers. CourseNana.COM

To avoid code duplication, move testing for metric or non-metric units to another helper function, is_metric. C does not have a special boolean type — instead, we use int. CourseNana.COM

However,ifyoureturnx==y,thiswillreturn0ifx!=yand1ifx==y. Usethisfactto streamline your code. CourseNana.COM

If the input was in a US customary unit, the value at this point must be in pounds. If the output must be in the metric system, we now convert the value to kilograms, using the symbolic constant LB_TO_KG. Likewise, if the input was in a metric unit, the value by now must be in kilograms, so, if the desired output unit is in the US customary system, we must convert it from kilograms to pounds using the same factor (but dividing instead of multiplying).
Now we have either pounds or kilograms in the
system of the desired output unit, but not necessarily in that unit itself. So we use the factors array again — this time dividing — in order to convert "out" from the output reference value to the value in the desired output unit, and return that value. CourseNana.COM

Back in main, then, you will have a while-loop that calls scanf as the while-loop condition. As mentioned, the scanf call should capture a double and two strings. Declare the variables to hold the captured values above the loop, as described above. Within the scanf loop, get and store the result of calling convert. You can then test for NAN by means of the C Standard Library function isnan, declared in math.h. (There is no other reliable way of detecting the NaN value — you cannot test for equality in the usual way.) In that case, print an error message (see above) and then allow the loop to continue, giving the user another chance. Otherwise, if the result is not NAN, print an equation showing the equivalent value in the desired unit, as shown. Alternatively, instead of first testing for an error and using the continue keyword, you can use if-else logic in either order — if convert returned NaN, print the error message, and otherwise print the result — or, if the return value is not NaN, print the result, and otherwise handle the error. CourseNana.COM

Now, the error message includes a reminder of the allowable units. This reminder is also contained in the initial instructions printed at start-up. So put that code into a separate helper function and call it from both places — where you print the instructions and where you handle NaN. Within that helper function — print_allowable_units — use the fact that you already have an array of allowable units to print them out by iterating over the array. CourseNana.COM

main returns EXIT_SUCCESS, as usual, showing that all has gone well. The order of items in pa1.c should be as follows: CourseNana.COM

Author headnote (with optional description). CourseNana.COM

#include directives, in alphabetical order.
Symbolic constant definitions, in alphabetical order:
LB_TO_KG
and MAX_UNIT_STRING_LENGTH.
Definition of the enumeration type
Unit, combined with a typedef statement to alias it as simply Unit. Definitions of the global constant (variable) arrays: unit_strings and factors.
Definitions of the helper functions:
unit_string_to_unit and is_metric.
Definition of the
convert function.
Definition of the helper function
print_allowable_units.
Definition of the
main function. Use the signature option without any parameters, since we are not using command-line arguments this time. CourseNana.COM

Developing and Building Your Program CourseNana.COM

Whenever you build your program, be sure to include the -Wall and -Werror flags: $ gcc -Wall -Werror -std=c99 pa1.c -o pa1 CourseNana.COM

The first flag, -Wall, tells GCC to display all error and warning messages and not to filter any out as less important. The second flag, -Werror, gets GCC to treat warnings as errors, which helps you to make sure that you have addressed both errors and warnings. Remember that you get an automatic 0 if you have any errors or warnings upon building. When we build your program for grading purposes, we use both flags. CourseNana.COM

As the C programming language has many versions, we need to let the compiler know which one we are using. The third flag -std=c99 lets the compiler know that we are using the standard version C99 (See more: http://en.m.wikipedia.org/wiki/C99 (http://en.m.wikipedia.org/wiki/C99) ). CourseNana.COM

Never write the whole program first before trying to build it. Alway write just a little bit, enough to build and test, and then add more code. You can figure out yourself how best to do that in this case. For instance, you can first "mock out" the convert function by having it always return some fixed value first and then go back and add more of the necessary details, step by step. Make frequent use of printing functions such as printf to get and check intermediate values as part of your development-and-testing procedure — and then remember to go back and delete them before finishing up. CourseNana.COM


CourseNana.COM

Get in Touch with Our Experts

WeChat (微信) WeChat (微信)
Whatsapp WhatsApp
Boston College代写,A General Mass Unit Converter代写,C代写,Boston College代编,A General Mass Unit Converter代编,C代编,Boston College代考,A General Mass Unit Converter代考,C代考,Boston Collegehelp,A General Mass Unit Converterhelp,Chelp,Boston College作业代写,A General Mass Unit Converter作业代写,C作业代写,Boston College编程代写,A General Mass Unit Converter编程代写,C编程代写,Boston Collegeprogramming help,A General Mass Unit Converterprogramming help,Cprogramming help,Boston Collegeassignment help,A General Mass Unit Converterassignment help,Cassignment help,Boston Collegesolution,A General Mass Unit Convertersolution,Csolution,