User Tools

Site Tools


haas:spring2015:cprog:projects:cbf0

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
haas:spring2015:cprog:projects:cbf0 [2015/03/20 19:45] – created wedgehaas:spring2015:cprog:projects:cbf0 [2015/03/22 15:15] (current) – [Program] wedge
Line 10: Line 10:
 =====Objective===== =====Objective=====
 To practice manipulating binary data in a C program (for fun and glory). To practice manipulating binary data in a C program (for fun and glory).
- 
-=====Prerequisites/Corequisites===== 
-In addition to the new skills required on previous projects, to successfully accomplish/perform this project, the listed resources/experiences need to be consulted/achieved: 
- 
-  * can perform this trick in your head/by hand (if you can't do it on your own, you have no business trying to tell the computer how to do it) 
-  * understand the pattern/process to doing it for any length number (2-digit through 18- or 19-digit) 
-    * digit length will depend upon size of user input variable (including signedness) 
-  * ability to deploy loops to simplify your process 
-  * ability to use arrays to facilitate the storage of your processed values 
-  * use of functions to modularize your code 
- 
-=====Scope===== 
-The allure of using (and learning) a programming language is to be able to effectively use it to solve problems, which in and of themselves are simulations of some process we can do in "the real world". 
- 
-In this case, we will be writing a program which will implement the mental math techniques for subtracting certain numbers from left to right-- seemingly against the grain from everything we've been taught. 
  
 =====Background===== =====Background=====
-This trick's full name is "All from Nine, the Last from Ten", and refers to central detail of the process we will be undertaking.+With the UNIX people exploring binary data, and using hex editors, and you being tasked with writing hex editor, it only makes sense to steer some of our activities towards the manipulation of binary data as well- one cannot effectively write a hex editor if they have no idea how to work with binary data.
  
-For starters, let us try it out:+This project aims to ameliorate that.
  
-<code> +Binary data merely refers to data as the computer stores it. The computer is a binary device, so its raw data (as it exists on various forms of storage and media) is often referred to as binary data, to reflect the 1s and 0s being represented.
- 1000 +
-- 941 +
- ==== +
-  059  +
-</code>+
  
-The thing is, we aren't going to be solving this the usual way. We're going to do it from left to rightSo, a walkthrough of what just happened:+The data we have become familiar with is textual data. We read from and write to files with the express purpose of storing text in themAnd with the use of various text processing tools, we can easily manipulate these text files.
  
-  * We start with the left-most digit to digit subtraction (the 0 - 9). As this isn't the last (right-most) subtraction, our key value is 9 (all from 9). Sohow much to add to 9 to get 9? **0**. That's our answer for that place. +Butdid you know that all text data is also binary data?
-  * Move one place to the right (0 - 4)... how much to add to 4 to get 9? **5**. Bam. +
-  * Move one place to the right-- we're now at the last digit. And last is from 10. So, how much to add to 1 to get 10**9**. +
-  * We see our answer is **059**.  +
- +
-Clearly, there are some prerequisites that need to be met in order to use this trick: +
- +
-  * the top number needs to be 1 followed by all zeros (the zeros is key). +
-  * the number we're subtracting is smaller than the number we're subtracting from. +
- +
-Try your hand at another: +
- +
-<code> +
- 1000000000000000 +
-- 928573956013453 +
- ================ +
-</code> +
- +
-Go ahead and try it (work it out on paper). +
- +
-The answer is: **071426043986547**+
  
 +The trick to remember is that its opposite is not always tre: not all binary data is text.
  
 +The computer works in units of **bytes**, which these days means groups of 8-bits. C has the ability to arbitrarily read and write individual bytes of data, and we will want to make use of that to aid us in our current task.
 =====Task===== =====Task=====
-The task at hand can benefit from loop and array assistance.+On lab46, in **/var/public/cprog/spring2015/cbf0/** is a file called **out.file**, a 124284 byte binary file that is essentially a scrambled JPEG file (originally called **cbf0.jpg**).
  
-For instance, taking the number input and processing it so each digit occupies its own array element would facilate your efforts in the overall task-- process strongly resembling some of the work you had to do in the **mbe1** project to get your input ready for the multiply by 11 activity.+Your task is to write C program to unscramble **out.file** and return it to its image-viewable **cbf0.jpg** state.
  
-=====Functions===== +For those who are in UNIXyou are not allowed to use any of the UNIX tools to accomplish this task: you must write a C program that does all the work.
-As indicated, this task shares many attributes with the **mbe1** project; in fact, the mental math process itself may be slightly simpler. That affords us the opportunity to introduce and learn about further programming optimizations, without the concurrent burden of new concepts.+
  
-Specifically, we will look at modularizing aspects of our solution, using functions, to make for a cleaner, more organized codebase.+The **out.file** data file has been scrambled as follows:
  
-We've been using functions all along (everytime you use **fprintf()** or **fscanf()**, for instance), but the value is not just in using pre-existing onesbut also in making our own to use.+  The last twelve consecutive 12 bytes (in incrementing orderof **cbf0.jpg** are the first twelve consecutive bytes of **out.file** 
 +  * The next previous twelve consecutive 12 bytes (in incrementing orderof **cbf0.jpg** are the next twelve consecutive bytes of **out.file** 
 +  * and so on until the file is "reversed", in units of 12 byte chunks (the individual bytes of the chunks have not had their order changed)
  
-====Function prototype==== +Your task is to write a C program that does the following:
-Like variables, functions need to be declared.+
  
-We can declare them at various scopes (file/global, block/local)... if you wish for the function to be accessible by all functions within a programyou will want to declare it with a global scope.+  * opens and reads **out.file** 
 +  * caches its entire contents in an array (don't waste space! use appropriately-sized data types) 
 +  * once loaded into memory, close **out.file** and open a new file for writing 
 +    * that new file will be called **/home/username/public_html/cbf0.jpg** (where "username" is your lab46 username) 
 +  * do the necessary processing to unscramble (unreverse) the reversed data, being mindful of those 12 byte chunks, to restore the original **cbf0.jpg** file in its specified location. 
 +  * once done, don't forget to close the file you had opened for writing
  
-If a particular function is only to be used by a specific function, and no others, you can opt to declare it local scope (ie within the function that will be calling it).+You can test the success of your program by pointing web browser at the following URL (being mindful to substitute in your lab46 username where "username" is specified):
  
-A function is basically a module or subroutineIt is a mini-program, focusing on the performing of particular process.+  * From outside the LAIR: http://lab46.corning-cc.edu/~username/cbf0.jpg 
 +  * If on a LAIR workstation: http://www/~username/cbf0.jpg
  
-Like a program, it takes input, does processing, and provides output. +Note that the "~" IS very much required.
- +
-Unlike a program, its input may not come from the keyboard, but instead from particular variables, and may not send output to the screen, but instead channel output in a way that it can be stored into a variable. +
- +
-This distinctions aside, a function can in many ways be viewed as a micro- or sub-program/routine. We use functions to assist us in making our code more readable/organized/navigable. +
- +
-Keeping everything in ONE file, ONE big function in that one file, is rather monolithic. In time, with sufficiently large programs, such an arrangement would become a tad unwieldy. So functions help to keep our focus short yet attentive. +
- +
-To create a function we must first declare (or prototype) it. This needs to happen BEFORE said function is ever used (just as with variables- you must declare a variable before it is first used, otherwise the compiler yells). +
- +
-A function, in many ways, is like a programmable variable (or is a variable with programming attached). +
- +
-As such, it has a return value of a type (the function's output), a name, and parameters (input). +
- +
-We see this with main()... here are two variations of a **main()** function declaration (technically also the start of the definition as well, in the case of **main()**): +
- +
-===Parameterless function=== +
- +
-<code c> +
-int main() +
-</code> +
- +
-In this example, we see the declaration of main() where it has a return value of **int**, meaning, upon completion, main() will return a value corresponding with an int data type (also in main()'s case, being the first function run, we tend to return a status code to the operating system-- 0 for success, non-zero for some sort of error or deferred success). +
- +
-main(), in this case, takes no parameters (just an empty set of parenthesis)... due to this, we refer to this function as a parameterless function. A function without parameters. Without input. +
- +
-Now: this is technically a different form of input and output than you are used to. Input doesn't ALWAYS have to come from the keyboard, nor does output ALWAYS have to go to the screen. Input instead is desired informating being acquired for the process at hand, and output is the byproduct of performing the operation. Sometimes this means keyboard input and screen output- but not always. +
- +
-Additionally, with or without parameters, we can always perform additional input (and output) within a given function, through the use of various input and output methods (like **fprintf()/fscanf()**). +
- +
-===Parametered function=== +
- +
-<code c> +
-int main(int argc, char **argv) +
-</code> +
- +
-In this case, our **main()** function actually takes parameters- two, in fact: +
- +
-  - an integer, we are calling **argc** +
-  - a double pointer, we are calling **argv** +
- +
-This function takes two parameters, two pieces of input, available to us in the form of variables, by those names, of those types. We make use of them as we need to in accomplishing the program at hand. +
- +
-So, when we wish to create functions of our own, we need: +
- +
-  * the return type +
-  * the function name +
-  * 0 or more parameters, identifying their order and type +
- +
-For example, let us make a sum() function. Here would be a likely prototype (we'd place it above main()): +
- +
-<code> +
-int sum(int *, int); +
-</code> +
- +
-A function prototype (vs. its definition) will have a terminating semi-colon, as you see above. +
- +
-In our case, our sum() function has the following: +
- +
-  * a return type of **int** (particular variable name doesn't matter, type does) +
-  * the function's name (sum) +
-  * a comma-separated list of types corresponding to the parameters (again, variable names do not matter, but the type is important). +
- +
-Our sum() function will take an integer array (denoted by the int pointer above), and a size (the second, regular int). +
- +
-Now, parameter order very much matters. In our case, an "int *" came first, followed by an "int"... we need to be mindful of this order to successfully call and use the function. +
- +
-====Function definition==== +
-While a function prototype is technically optional (you can put the definition in place of the prototype-- we just often use prototypes to further allow organization), we MUST have a function definition. This is nothing short of the code that dictates what operations the function in question will perform. +
- +
-Our sum() function will be defined (below the main() function) as follows: +
- +
-<code c> +
-int sum(int *array, int size) +
-+
-    int result = 0; +
-    int i = 0; +
-     +
-    for (i = 0; i < size; i++) +
-        result = result + array[i]; +
-         +
-    return(result); +
-+
-</code> +
- +
-====function calling==== +
-Once we've declared (prototyped) and defined our function, now all we have to do is use it! When you make use of a function, we refer to it as //calling//. We call the function, by name, providing and required parameters, and capturing any return value as we see fit. +
- +
-Here would be an example of calling the above-mentioned **sum()** function: +
- +
-<code c> +
-int scores[4]; +
-int tally = 0; +
- +
-scores[0] = 88; +
-scores[1] = 47; +
-scores[2] = 96; +
-scores[3] = 73; +
- +
-tally = sum(scores, 4); +
-</code> +
- +
-Note, that it is rather important to match the type and order of parameters. Due to the nature of the array (especially the form of array declaration) used, certain pointer-related details are being hidden from us, giving somewhat of a false impression. Further discussion about pointers will begin to shed light on that. +
- +
- +
-=====Program===== +
-It is your task to write a program that obtains a long integer value from the user, and processes that single value into separate array elements (one digit per array element). Determining the number of digits, you are to perform this "all from nine, last from ten" subtraction method on the number using array transactions, displaying a visual representation of the problem being solved to STDOUT. +
- +
-Your program should: +
-  * obtain its input from STDIN. +
-    * input should be in the form of a single (long) long integer value (you want a 64-bit data type) +
-  * determine the number of digits of the inputted value (store this in a variable) +
-  * process that input long integer into separate array elements- one digit per element. +
-    * you may assume a maximum array size of the maximum number of digits you're theoretically able to input that can be stored in a 64-bit value. +
-  * perform the "all from nine, the last from ten" operation on the array, storing the result in another array. +
-  * display the problem being solved, along with the answer +
-  * use functions to modularize your code: +
-    * have an **longint2array()** function that takes the long int, and returns an array (the function itself handles the processing of splitting up the long int into individual digits). +
-    * have a **printarray()** function, whose responsibility it is to display the indicated array to STDOUT. +
-    * have a **allfromnine()** function that takes the source array, does the processing, and returns ther result array. +
- +
-I might suggest the following function prototypes: +
- +
-<code c> +
-unsigned char *longint2array(unsigned long int); +
-void printarray(unsigned char *, unsigned char); +
-unsigned char *allfromnine(unsigned char *); +
-</code> +
- +
-Some questions to contemplate: +
- +
-  * Why an array of unsigned chars when we're starting with a long (long) int? +
-    * Why is that the "best fit" size-wise? +
-    * Why will that not result in lost data? +
-  * Why unsigned? +
-    * What impact will that have on our input value's upper bound? +
-  * Why represent the size of the usable array as an unsigned char? +
-    * Why is this the "best fit" size-wise? +
-=====Execution===== +
-An example of your program in action: +
- +
-<cli> +
-lab46:~/src/cprog/afn0$ ./afn0 +
-Enter value: 31415926535897 +
-Digits detected: 14+
  
- 100000000000000 +If you are successful, the image should render itself in the browser, and you should be able to recognize it (vs. it being unreadable and unrecognizable). The image is intended to be meme-like in original, and hopefully will invoke a mild sense of humor (that of course is optional).
-31415926535897 +
- --------------- +
-  68584073464102+
  
-lab46:~/src/cprog/afn0$  
-</cli> 
  
 =====Submission===== =====Submission=====
Line 242: Line 61:
  
   * Code must compile cleanly (no warnings or errors)   * Code must compile cleanly (no warnings or errors)
-  * Output must be correct, and resemble the form given in the sample output above.+  * Final image must be viewable.
   * Code must be nicely and consistently indented (you may use the **indent** tool)   * Code must be nicely and consistently indented (you may use the **indent** tool)
-  * Code must utilize the algorithm presented above+  * Code must utilize the specifications presented above
   * Code must be commented   * Code must be commented
     * have a properly filled-out comment banner at the top     * have a properly filled-out comment banner at the top
Line 250: Line 69:
   * Track/version the source code in a repository   * Track/version the source code in a repository
   * Submit a copy of your source code to me using the **submit** tool.   * Submit a copy of your source code to me using the **submit** tool.
 +    * You are to submit 3 files:
 +      * your C source code to accomplish this task
 +      * your copy of out.file
 +      * your processed cbf0.jpg file
  
 To submit this program to me using the **submit** tool, run the following command at your lab46 prompt: To submit this program to me using the **submit** tool, run the following command at your lab46 prompt:
  
 <cli> <cli>
-$ submit cprog afn0 afn0.c +$ submit cprog cbf0 cbf0.c out.file /home/username/public_html/cbf0.jpg 
-Submitting cprog project "afn0": +Submitting cprog project "cbf0": 
-    -> afn0.c(OK)+    -> cbf0.c(OK) 
 +    -> out.file(OK) 
 +    -> /home/username/public_html/cbf0.jpg(OK)
  
 SUCCESSFULLY SUBMITTED SUCCESSFULLY SUBMITTED
haas/spring2015/cprog/projects/cbf0.1426880701.txt.gz · Last modified: 2015/03/20 19:45 by wedge