Search This Blog

Simplicity is the ultimate sophistication.” — Leonardo da Vinci
Contact me: sreramk360@gmail.com

Wednesday, 25 February 2015

A thought that rules you


A thought that rules you
 

We don't tend to think about how lucky we are if our thoughts are crowded with worries. Please don't stop reading, seeing this as another boring advice someone across the world gives you while you have many people around you to flood you with advices; this is going to be different. Before I proceed with this article, let me tell you that I am not an expert in subject areas like human psychology or social psychology or on any other related fields. So what I say now are just stuff I think are true and it does not go beyond that.

In this article, I am going to talk about thoughts which rule you through your daily course of life with or without your knowledge. As we cross our adolescence age, we tend to comprehend more information compared to our early life. I believe its because we retain more information and consider more thoughts at the same time. Have you ever realized how you could write down what was dictated without the slightest thought of actually writing it? What I mean is, when we note down something that's being dictated, our hand moves automatically, writing down the words. Have you ever realized how you could walk around without even thinking about walking?

This one answer depicts the solution to all our problems. I don't believe in giving meaningless advices that had been repeated over a million times in different places and different languages. If you had seen my other posts, you would realize that I love solving problems down to its finest detail rather than giving an abstract over view of the solution. The same way I am going to give you a fine detailed solution which states the root cause of all your problems. I believe its true; it doesn't mean that the scientific society must accept it (I have no professional knowledge in psychology). When I talk about a thought that rules you, I mean to say that certain thoughts exist within your head with or without your knowledge, which organizes your behavior at the most fundamental level. Now I guess my example of writing a dictated text in a piece of paper makes sense to you. Yes I believe its the "thought" that listens to the word that's being dictated, find its spelling, recollects how to write it down and finally writes it down without you recognizing all these details. Labeling this attribute as "thought" might not be correct; but in this article, that's how I am going to call it.

Now let me give you another example: "our planet earth is a part of a tiny solar system, among billion others, together which constitutes our galaxy". Did you think about galaxies a second before you read this? probably no, right? You might have had other thoughts in your mind before you read this sentence. And is what I said now new to you? Of course not! But why didn't you have that piece of thought in your mind when you actually knew it? Its because, we don't think about everything we know or have known before (or have forgotten it). Then how did my sentence make you recollect them in not less than a fraction of a second? I am not a scientist dealing with brain, so my answer would be "that's how our brain works!". My explanation is, once we have a thought similar or in someway associated with another thought or a peace of memory in our brain, then that piece of thought gets recollected automatically without us showing any effort. Once the new thought comes to your mind, either you accept it or reject it. when you reject it, then your thread of thoughts on that particular matter is broken. but if you persist thinking about it, newer thoughts associated with the previous thought starts popping up in your head.            

Until now, I guess I had talked about two kinds of thoughts; one that immediately induces an action and the other which just remains passive in our head (without inducing any action directly, unless we respond to it). There are parts of it you can control, and there are parts of it you cannot control. Lets consider the second example first, where you didn't have the slightest idea what a galaxy was the moment before you read about it. Now, being aware of the sentence I had written down above got you reminded about galaxies; do you think its ever possible for you to read that sentence and not be reminded about galaxies. I had used the word galaxy extensively, until now. Could you stop thinking about it the moment I ask you to do so? possibly not! So you need to become aware of what you cannot control, so that you could get yourself to control the parts of your life you can control. Every human on this world has the power to induce change. The most challenging part of it is, each of us have different means by which we can induce a change practically. The first example I had given you makes it clear that you don't consider each detail of the work you do, instead let your brain takeover your actions. So this is again something that your brain does without your knowledge. Can we give other examples similar to this? The example of walking and writing were positive ones, now let me give you a negative example from my life, before I had changed; realizing all this.

Almost every day, I plan a study schedule for the evening; but when I come home, I throw my backpack, and sit before the computer or read my novel. I just tend to think, "let me do it tomorrow. I am a bit too tired today". I keep postponing my work until it accumulates to a big bundle. In the morning, before going to my college, I feel that my mode is opt for studying and nothing in the world can stop me from doing so, when I get back home I find that I was wrong! not for a day or two, but for months! And this thought made me feel more miserable and made me avoid studying even more intensively. I would always have some work to do; but though I could do those works, I won't be able to bring myself to do my college work. Some other time in the same year, I start studying studiously (like a nerd) and score well. Why am I not able to both at the same time? and what's making it impossible for me to switch from one to another? During the time of the year when I do my project work, I don't maintain the continuity of my studies and hence loose my temporary habits (or I forget the "thoughts" that had helped me to keep my studying phase) that aid me in my academical studies.

Reading right before exams seem completely impossible for me. I won't be able to get myself seated before my study table. This is again because of that "thought" or the habit that got erased once I had reduced paying heed to my academical studies. These "thoughts" are usually impossible to appose and change in a short period of time. For stuffs that are good, then these thoughts need not be changed. But for stuff that are bad or harmful or depressing, we would desperately need a change. Why do you think happiness lies in possessing something you don't have? The explanation to this dates back to the days you were young. Young children (below the age of three), usually will want to hold new stuff in their hand, feel it, smell it and taste it. Older children (about age five, six and seven) will be curious to handle stuff they see their parents handle (like the car's driver's seat. Its the best example, children would want to drive a vehicle even if they are aware that they won't be allowed to do so). But unfortunately, children are not given everything they ask; it could either be an expensive toy or the aeroplane that flies overhead! This intention (to posses something they are not given)  gets cultivated and intensifies as they grow older. Initially, their intention to handle fancy objects were induced by their curiosity. But as they get older, they tend to associate possessing something they don't have with "victory" or "happiness". Later, as he grows more older, his desire to own stuff he doesn't have increases drastically.

So hence, most people "want everything". I don't have any objection to your views, but I just want to say that the source of happiness is yourself, and not something outside. Its because, it was you who associated happiness with materialistic gain when you were young.  


copyright (c) 2015 K Sreram. You may not distribute this article without the concerned permission from K Sreram.  
About my blog 

Sunday, 22 February 2015

Proof the vector dot product and cross product are distributive

Proof that vector dot product is distributive

We may write a vector product $\vec{a}.\vec{b}$ as $ |a||b|cos\theta$, by definition. For expressing an n-dimensional Euclidean space we may use the summation notation $\vec{a} = \sum \limits_{i=0}^n a_i \hat k$. The magnitude of a vector quantity $|\vec{a}|$ can be expressed as $|\vec{a}|^2 = \sum\limits_{i=0}^n {a_i}^n$. The proof of this expression directly follows from the Pythagoras theorem which states that, the magnitude of the line joining the ends of the line segments that emerges mutually perpendicularly from a point in space is equal to the square root of the sum of the squares of the magnitude of the other two line segments. Here, two mutually perpendicular lines are taken; the same way, while extending this to three dimensional space in which we introduce another axis perpendicular to the plane in on which the right angled triangle lies. Lets extend another line across this third axis from the point we initially considered. The hypotenuses of the triangle, which was computed using the Pythagoras theorem, is defined to be perpendicular to the newly drawn line. This is because, the third axis is perpendicular to the plain on which we constructed our first triangle.

Because the hypotenuses lies on the plain, it becomes perpendicular to the third line. Now consider this new line and the hypotenuses to lie on another plane which cuts through the three dimensional coordinate system irregularly. We now have two perpendicular lines in this new plain which we again root the sum of the squares of their magnitudes to get the magnitude of another line which is the hypotenuse of this system of lines. Thereby we can say that the newly formed hypotenuse is the magnitude of the line joining the origin and the point $(x,y,z)$ in three dimensional space, if the point we initially considered is the origin of this three dimensional co-ordinate system. Now we may extend this to higher dimensions by introducing another axis which we define to be perpendicular to all the other three axis. Like our example of extending a two dimensional vector analysis to three dimensions by just considering the magnitude of a single line formed by the two axis; introducing another axis, does not complicate our process of generalizing our expression of vector magnitude to another dimension if we only consider the system of the third axis and the single line plotted previously.

Now, for extending this to higher dimensions, we may do the same. Lets just consider the three-dimensional magnitude of an n-dimensional line (by just neglecting the higher dimensions); its practically impossible to imagine another dimension. But we a find the magnitude of a four-spatial dimensional line by the expression $l_4 = \sqrt{{l_3}^2+{k_4}^2}$ (where, $l_3 = \sqrt{{k_1}^2+{k_2}^2+{k_3}^2}$ ). We know that the fourth line is perpendicular to the first three mutually perpendicular lines, but it's not necessary to imagine it practically to compute its magnitude in the 4D co-ordinate system. We have the magnitude $k_4$ and the line $l_3$ so they form a plane that irregularly cuts the 4D co-ordinate system, but again, we have a plain to which we can freely apply the Pythagoras theorem.

So now lets proceed to prove the distributive property of  vector dot product. To prove it, we have to show that $\vec{c}.(\vec{a}+\vec{b}) = |\vec{c}||\vec{a}+\vec{b}|cos{\theta}_{a+b,c} = |\vec{c}|     |\vec{a}|cos{\theta}_{a,c}+ |\vec{c}||\vec{b}|cos{\theta}_{b,c}$. To proceed with this proof, we have to show that $|\vec{a}+\vec{b}|^2 = |\vec{a}|^2 + |\vec{b}|^2 + 2|\vec{a}||\vec{b}|cos{\theta}_{a,b}$ and then show that $\vec{a}.\vec{b} = \sum\limits_{i=0}^n a_ib_i$.

The parallelogram law of vector addition can be proved in the following way (proof for the parallelogram law of vector addition),


   Let, $OA$ be the vector component $\vec{a}$ and let $OC$ be the vector component $\vec{b}$ and let $OB$ be the vector component $\vec{a}+\vec{b}$. Now lets express the length $OB$ in terms of $|\vec{a}|$ and $|\vec{b}|$ and the angle $\angle{BCD}$.  $\angle{BCD} = \angle{AOC}$ as the above diagram is a parallelogram. We can say that $OA = CB = |\vec{a}|$ and so we get, $CD = CB.cos\angle{BCD} = |\vec{a}|.cos\angle{BCD}$. Now, as we have $CD$  and $OC$ we can write $OD = OC+CD$ or, $OD = |\vec{b}| + |\vec{a}|.cos\angle{BCD}$. Now we can express $BD$ as, $BD = |\vec{a}|.sin\angle{BCD}$.

$${OB}^2 = |\vec{a}+\vec{b}|^2 = {BD}^2 + {OD}^2 $$
So we can write $$|\vec{a}+\vec{b}|^2 =  (|\vec{a}|.sin\angle{BCD})^2 + (|\vec{b}| + |\vec{a}|.cos\angle{BCD})^2 $$.

After simplification we get, $$|\vec{a}+\vec{b}|^2 = |\vec{a}|^2 + |\vec{b}|^2 + 2|\vec{a}||\vec{b}|cos{\theta}_{a,b}$$

proof that $\vec{a}.\vec{b} = \sum\limits_{i=0}^n a_ib_i$:

Now, lets proceed with proving the distributive property of vector dot product. We first need to show that,  $$\vec{a}.\vec{b} = \sum\limits_{i=0}^n a_ib_i$$. From the parallelogram law of vector addition we have $$cos\theta_{a,b} = \frac {|\vec{a}+\vec{b}|^2 - |\vec{a}|^2 - |\vec{b}|^2}{2|\vec{a}||\vec{b}|}$$. This can be rewritten in its summation form as,

$$cos\theta_{a,b} =
\frac {
              |\sum \limits_{i=0}^n a_i \hat k +
                                         \sum \limits_{i=0}^n b_i \hat k|^2 -
                                                               |\sum \limits_{i=0}^n a_i \hat k|^2 -
                                                                           |\sum \limits_{i=0}^n b_i \hat k|^2
         }
        {
                  2|\sum \limits_{i=0}^n a_i \hat k|
                   |\sum \limits_{i=0}^n b_i \hat k|
         }
$$ Or,

$$cos\theta_{a,b} =
\frac {
              |\sum \limits_{i=0}^n (a_i+b_i) \hat k|^2-
                                                               |\sum \limits_{i=0}^n a_i \hat k|^2 -
                                                                           |\sum \limits_{i=0}^n b_i \hat k|^2
         }
        {
                  2|\sum \limits_{i=0}^n a_i \hat k|
                   |\sum \limits_{i=0}^n b_i \hat k|
         }
$$ Or, 
$$cos\theta_{a,b} =
\frac {
              \sum \limits_{i=0}^n (a_i+b_i)^2-
                                                               \sum \limits_{i=0}^n {a_i }^2 -
                                                                           \sum \limits_{i=0}^n {b_i}^2
         }
        {
                  2\sqrt{\sum \limits_{i=0}^n {a_i}^2
                   \sum \limits_{i=0}^n {b_i}^2}
         }
$$ We know that, 

$$\vec{a}.\vec{b} = |\vec{a}||\vec{b}|cos\theta_{a,b}$$ Or, 

$$\vec{a}.\vec{b} = (\frac {
              \sum \limits_{i=0}^n (a_i+b_i)^2-
                                                               \sum \limits_{i=0}^n {a_i }^2 -
                                                                           \sum \limits_{i=0}^n {b_i}^2
         }
        {
                  2\sqrt{\sum \limits_{i=0}^n {a_i}^2
                   \sum \limits_{i=0}^n {b_i}^2}
         }
)                 \sqrt{ \sum \limits_{i=0}^n {a_i}^2                    \sum \limits_{i=0}^n {b_i}^2} $$ Or, 
$$ \vec{a}.\vec{b} = \frac{\sum \limits_{i=0}^n ({a_i}^2 + {b_i}^2 + 2{a_i}{b_i})-                                                               \sum \limits_{i=0}^n {a_i }^2 -
                                                                           \sum \limits_{i=0}^n {b_i}^2}{2} $$ Or,
$$\vec{a}.\vec{b} = \sum\limits_{i=0}^n a_ib_i$$

Proof that $(\vec{a} + \vec{b}) .\vec{c} = \vec{a}.\vec{c} + \vec{b}.\vec{c}$:

On substituting the result $\vec{x}.\vec{y} = \sum\limits_{i=0}^n x_iy_i$ in the expression we get,

$$
(\vec{a} + \vec{b}) .\vec{c} =
              \sum\limits_{i=0}^n (a_i+b_i)c_i =
                              \sum\limits_{i=0}^n (a_ic_i+b_ic_i) =
                                          \sum\limits_{i=0}^n (a_ic_i) + \sum\limits_{i=0}^n (b_ic_i)
 $$.
Now consider the RHS of the equation $(\vec{a} + \vec{b}) .\vec{c} = \vec{a}.\vec{c} + \vec{b}.\vec{c}$$; again on substituting the same result in it, we get:
$$\vec{a}.\vec{c} + \vec{b}.\vec{c} = \sum\limits_{i=0}^n (a_ic_i) + \sum\limits_{i=0}^n (b_ic_i)$$, which is same as the LHS. Hence we have proved that LHS = RHS or,
$(\vec{a} + \vec{b}) .\vec{c} = \vec{a}.\vec{c} + \vec{b}.\vec{c}$ 

Now lets show that $\vec{c}\times(\vec{a}+\vec{b}) = (\vec{c}\times \vec{a} + \vec{c}\times \vec{b})$. By proving this, we would be proving that the cross product of the sum of two vector quantities is distributive in nature. 

A vector cross product is defined as, $\vec{a}\times\vec{b} = |\vec{a}||\vec{b}|sin\theta_{a,b}\hat n$. This expression, like the expression for the vector dot product is considered to be the basic definition we introduce.The unit vector $\hat n$ shows the direction perpendicular to the plane which contains the lines $\vec{a}$ and $\vec{b}$. We know that 
$\vec{a}.\vec{b} = |\vec{a}||\vec{b}|cos\theta_{a,b}$, so we may convert it to $|\vec{a}||\vec{b}|sin\theta_{a,b}$ by squaring the dot product expression shown above and subtracting it from $|\vec{a}||\vec{b}|$. I.e., 

$$(|\vec{a}||\vec{b}|)^2 - (\vec{a}.\vec{b})^2 = (|\vec{a}||\vec{b}|)^2 -  (|\vec{a}|^2|\vec{b}|^2cos^2\theta_{a,b})^2$$ which is same as,

$$ (|\vec{a}||\vec{b}|)^2 - (\vec{a}.\vec{b})^2  = |\vec{a}|^2|\vec{b}|^2sin^2\theta_{a,b}$$

or we may write,

$$[(|\vec{a}||\vec{b}|)^2 - (\vec{a}.\vec{b})^2]\hat n  = |\vec{a}|^2|\vec{b}|^2sin^2\theta_{a,b}\hat n$$. Or, 

$$\vec{a}\times\vec{b}  = |\vec{a}||\vec{b}|sin\theta_{a,b}\hat n =\sqrt{ (|\vec{a}||\vec{b}|)^2 -  (|\vec{a}||\vec{b}|cos\theta_{a,b})^2}\hat n$$.

From the parallelogram law of vector addition, we know that $cos\theta_{a,b} = \frac {|\vec{a}+\vec{b}|^2 - |\vec{a}|^2 - |\vec{b}|^2}{2|\vec{a}||\vec{b}|}$ so, $sin\theta_{a,b} = \sqrt(1- [\frac {|\vec{a}+\vec{b}|^2 - |\vec{a}|^2 - |\vec{b}|^2}{2|\vec{a}||\vec{b}|}]^2)$. Now, we may write this as,
$$sin\theta_{a,b} = \sqrt{
\frac { 4(\sum \limits_{i=0}^n {a_i}^2
                  \sum \limits_{i=0}^n {b_i}^2) -
      (\sum \limits_{i=0}^n (a_i+b_i)^2-
         \sum \limits_{i=0}^n {a_i }^2-
                \sum \limits_{i=0}^n {b_i}^2)^2
         }
        {
                  4(\sum \limits_{i=0}^n {a_i}^2
                   \sum \limits_{i=0}^n {b_i}^2)
         }
   }
$$ Or,
$$|\vec a||\vec b|sin\theta_{a,b} =
\frac { \sqrt{
                4(\sum \limits_{i=0}^n {a_i}^2
                  \sum \limits_{i=0}^n {b_i}^2) -
      (\sum \limits_{i=0}^n (a_i+b_i)^2-
         \sum \limits_{i=0}^n {a_i }^2-
                \sum \limits_{i=0}^n {b_i}^2)^2
               }
         }
        {
                 2
         }

$$Or,
$$|\vec a||\vec b|sin\theta_{a,b} =
\frac { \sqrt{
                4(\sum \limits_{i=0}^n {a_i}^2
                  \sum \limits_{i=0}^n {b_i}^2) -
      (2\sum \limits_{i=0}^n (a_ib_i))^2
               }
         }
        {
                2
        }
$$ Or,
$$|\vec a||\vec b|sin\theta_{a,b} =
 \sqrt{
          (\sum \limits_{i=0}^n {a_i}^2
                  \sum \limits_{i=0}^n {b_i}^2) -
      (\sum \limits_{i=0}^n (a_ib_i))^2
               }
$$Or,

$$|\vec a||\vec b|sin\theta_{a,b} =
 \sqrt{
          (\sum \limits_{i=0}^n\sum \limits_{j=0}^n {a_i}^2{b_j}^2) -
      (\sum \limits_{i=0}^n\sum \limits_{j=0}^n (a_ib_i)(a_jb_j))
               }
$$ 

On simplification, we may write this as,

$$|\vec a||\vec b|sin\theta_{a,b} =
 \sqrt{
         (-\sum \limits_{i=0}^n\sum \limits_{j=0}^n a_ib_j)^2, i\not=j
               }
$$ Which implies,

$$|\vec a||\vec b|sin\theta_{a,b} = \sum \limits_{i=0}^n\sum \limits_{j=0}^n a_ib_j, i\not=j $$ Now, multiplying both sides with $\hat n$ we get, $$\vec{a}\times\vec{b} = (\sum \limits_{i=0}^n\sum \limits_{j=0}^n a_ib_j) \hat n, i\not=j $$







copyright (c) 2015 K Sreram. You may not distribute this article without the concerned permission from K Sreram.  

About my blog

Friday, 20 February 2015

Learn files in C tutorial 3

Learn files programming in C: practical tutorial 3 (Brief introduction to files in C)


"In the Last tutorial, I got a bit carried away. The first question I asked was a bit too much for most C beginners; but if you have a good experience programming in other languages and had shifted to learning C, then I guess that the previous tutorial might have been of at-most use to you in understanding basic C file handling functions." -K Sreram 

"To follow this tutorial, you should be familiar with the concepts listed in the tutorial 1 and should have gone through tutorial 2. If you didn't understand the entire program in tutorial 2, don't worry. It will soon make sense as you follow these tutorials. 

"To follow this tutorial you should be familiar with the basic file opening and closing operations using fopen, fclose; and should also be familiar with fscanf and fprintf operations to do simple read write operations."

fprintf and fscanf functions are not opt for reading and writing binary data to a file. The reason is, many internal conversions take place during the read/write process. Not all operating systems have the same binary value for next line, enter, back space or just space characters. If you write a program and want it to be portable, you choose the functions to use carefully. Here, you don't always consider the working of your program but consider the actual purpose of the function you use. If fprintf is used, it means you have intended to write text to a destined file. If  you use fprintf like a binary writing function, you must note that you could allow unexpected conversions to take place, if the program was compiled for a different platform. Also using these functions for binary read-write is a bad practice as it could affect the readability of your source. After all what matters is portability and readability of your source code. And more over, the extra conversations are brought about by extra processes (which does the task of checking, rearranging, etc.,) which takes place apart from reading the data from the file, which is not time-vice efficient (if you intend to use fprintf like fwrite). 

As listed out in tutorial 1, there are a variety of functions for read and write; its better to know all of them; we may choose the one opt for the particular situation we face. Let me give you example programs using those functions and explain their use in detail.

Section 1: using functions fopen, fclose, fgets, fputs 
    program 1: using functions fopen, fgets, fclose:
/*
* this program example uses fgets function to get an input from a file that already exist
* prototype: char* fgets (char* variable, int size, FILE* fileStream);
*/
#include <stdio.h> // for functions: fopen, fgets, fclose
#include <conio.h> // for function: getch
int main()
{
    char text[100];
    FILE* f = fopen("fName.txt", "r"); //opens file named fName.txt, present in the local directory in read mode
    if(f==NULL) // checks if the file opened correctly
    {
        printf("error: unable to open file fName.txt");
        getch();
        return -1; // returns error signal
    }
    while(!(fgets(text, sizeof(char)*100, f)==NULL)) //attempts to read data from the file using gets
        printf("%s\n", &text); // displays the data
        /* This function causes data to be read in blocks of sizeof(char)*100 units each time. Each time the
         * characters are read, they are displayed on the application's console output screen. It stops reading
         * a line either if it encounters a next line character or the exceeds the size (here its 100)
         */
    fclose(f); // clearing all pointers and closing the stream
    getch();
    return 0;
}

This program just reads data from a file and displays them on the screen. Note that we had given the size of the text variable as a parameter along with the C string as another parameter and the stream to which the data is to be written as another parameter. This size parameter ensures that only a certain number of characters are read from the steam and written to the variable named 'text'; its also to ensure the safety of the function. The at-most number of values the 'text' parameter can hold is of size 'sizeof(char)*100'. If the value entered exceeds the maximum size of the C string, we can expect a run-time error of attempting to access an inaccessible memory location. when we either declare a variable or dynamically allocate one, a specific memory location automatically gets reserved for our program. If we attempt to read from a memory location that's not reserved for our program, then the operating system terminates the program immediately. The fgets function stops reading and returns when it comes across the following characters: '\n', '\0', '\r'. fgets returns the pointer to the string text, in the above case; if the read operation had been a failure, it returns the value NULL. Again, this function is only used for text based read operation. 

basic causes for the failure of "fgets" operation (during failure, fgets returns NULL):
  1. The file being read is accessed by another application.
  2. The end-of-file is reached. 
program 2: using functions fopen, fputs, fclose:

/*
* this program example uses fputs function to write to a file
* prototype: int fputs (char* variable, FILE* fileStream);
*/
#include <stdio.h> // for functions: fopen, fgets, fclose
#include <conio.h> // for function: getch
#include <strings.h>
int main()
{
    char text[100];
    FILE* f = fopen("fName.txt", "w"); //opens file named fName.txt, present in the local directory in write mode
    if(f==NULL) // checks if the file opened correctly
    {
        printf("error: unable to open file fName.txt");
        getch();
        return -1; // returns error signal
    }
    while (1)// starts an infinite loop
    {
        gets(text); // obtains the text as input
        if(strcmp(text, "exit") == NULL) // checks for the string in text: if its "exit" the loop terminates
            break;
        if(fputs(text, f) == EOF) // writes data to file, and checks if its done right.
        {
            printf("unable to write to file");
            getch();
            return -1;
        }

    }

    fclose(f); // clearing all pointers and closing the stream
    getch();
    return 0;
}

There is one difference between determining end-of-file, while reading data from a file using fgets and writing data do a file using fputs, fgets does not return an integer type signal of the status of reading from the file, instead returns the pointer to the C string to which the read data is stored; In case of failure, a null pointer is returned (i.e., 0). Whereas, fputs returns EOF (or -1) in case of failure and zero in case of success. There is a specific function in C for testing if the file had reached the end-of-file. Its 'int feof(FILE* streamName);' this returns a non zero value when the pointer had reached the end-of-file. This signals the end of file. But if the pointer hadn't reached the file's end, zero is returned.      

Using feof when other functions used here accomplishes the same task is not desirable. In this case, the run-time of the program is very less and making slight changes such as adding an feof function to detect the file's end (while reading the data from file) is not going to make any difference. But in real time situations where each function is bound to be called many times before the termination of a particular task or the program, we may avoid calling certain functions often or unnecessary as it could hinder the run-time of the task or the application drastically.   

program 3: using functions fopen, fclose, fgets, fputs:
/*
*  program to copy the contents of a text file to another;
*/

#include <stdio.h>
int main()
{
    FILE *f_read, *f_write; // a stream for reading and another stream for writing
    char readFile[260],writeFile[260]; // names of files or directories are stored here. Note that
                            // for windows operating system, the value 260 denotes the maximum
                            // size of a file name
    char data[100]; // a C string used as a temporary buffer to store read data and to write
                 // it to the destined file.

    printf("enter the name of the file to read from (or its directory):"); // get the names or paths of the files
    gets(readFile);
    printf("enter the name of the file to write to (or its directory):");
    gets(writeFile);

    f_read = fopen(readFile, "r"); // opens the first stream in read mode
    f_write = fopen(writeFile, "w"); // opens the second stream in write mode

    while(!(fgets(data, 100, f_read) == NULL)) // gets data until a read error occurs.
        fputs(data, f_write); //writes data to stream.

    fclose(f_read); // close the streams and clear all memory.
    fclose(f_write);
    // an alternative to substitute the above two statements could be fcloseall()
    return 0;
}

The above code asks for the name/path of the source file to read from and the name/path of the destination file. It then opens both the files and links them to the streams 'f_read' and 'f_write' declared in the main function. Once they are open, the function 'fgets' is made to read data from the file associated with the stream 'f_read' and writes them to the file associated with the stream 'f_write'. This read/write process continues until the 'fgets' function encounters an error. This happens when the file's pointer had reached the file's end.

After the read/write process gets over, both the streams are closed. In this example, both the streams were closed separately, but in situations where there are more than one streams opened and its needed to close them all, then the function 'fcloseall()' can be called. This function closes all the streams other than the basic ones like 'stdin', 'stdout' and 'stderr'.   

Section 2: using functions fopen, fclose, fgetc, fputc:
 program 1: using functions fopen, fclose, fgetc
/*
* program to count the number of a give character in a particular file using getc
*/

#include <stdio.h>
#include <conio.h>
int main()
{
    int count = 0;
    char fName[260], ch, ch2;
    FILE *f;
    printf("enter the file name:");
    gets(fName);
    printf("\nenter the character to search:");
    scanf("%c", &ch);
    f = fopen(fName, "r");
    if(f == NULL)
    {
        printf("error opening file %s", fName);
        return -1;
    }

    while(!((ch2=fgetc(f))==EOF)) //fgetc returns the character that was read from the stream f
        if(ch == ch2)   // it returns -1 in case of error. It is because, there isn't any text based
            ++count;   // character with the value -1.

    printf("number of %c's in the file %s is %d", ch, fName,count);
    fclose(f);
    getch();
    return 0;
}
 
Note that the function fgetc can be interchangeably written as getc. The only difference is, getc is a macro, which is dangerous at some times, and fgetc is a function. Macros are sometimes unsafe. lets say you have a macro defined as '#define foo(a) a*(a+1)/2'. Now, lets pass on an argument, 'b = b+1' to the macro foo. Lets say, foo(b = b +1 ) is written in the calling function. Then, before compilation the macro foo(b = b + 1) is changed to, (b = b + 1)*((b = b + 1)+1)/2. If you watch closely, b is incremented by one twice! this deceives the programmer into believing that b does not increment twice but just increments once, by just glancing at the line 'foo(b = b + 1)'. This makes it more difficult to debug. So its better to use a function rather than a macro. But if you persist on using a macro rather than a function, its advisable to define the macro as an inline statement. 

program 2: using functions fopen, fclose, fgetc, fputc:

/*
* program to read text form a text file and convert each sentence's
* starting word's starting letter to upper case. There is a grammatical
* rule in English according to which the sentence's starting word's starting
* letter should be made upper case compulsorily.
*/

#include <stdio.h>
#include <conio.h>
#include <ctype.h>// for isalpha and toupper
int main()
{
    FILE *fr, *fw;
    char rfName[260], wfName[260], data;
    int truth = 1; // signals 1 if the next character read should be converted to upper-case

    printf("enter the name of the file to read from (or the directory):");
    gets(rfName);
    printf("\nenter the name of the file to write to (or its directory):");
    gets(wfName);

    fr = fopen(rfName, "r");
    if(fr == NULL)
    {
        printf("\nunable to open file %s", rfName);
        return -1;
    }

    fw = fopen(wfName, "w");
    if(fw == NULL)
    {
        printf("\nunable to open file %s", wfName);
        return -1;
    }

    while(!feof(fr))
    {
        data = fgetc(fr);
        if(data == EOF)
        {
            printf("error: reading data from file");
            return -1;
        }
        else if(data == '.' || data == '!' || data == '?')
                truth = 1;
        else if(isalpha(data) && truth)
                {
                    data = toupper(data);
                    truth = 0;
                }
        if(fputc(data, fw) == EOF) // fputc returns EOF if there was a error reading and sets stderr
        {
            printf("error writing to file");
            return -1;
        }
    }
    fclose(fw);
    fclose(fw);
    getch();
    return 0;
}
 

This program helps the user convert the starting letter of each sentence to capital, is the user had forgotten to do so. The program reads a character from the file to be read from and checks if its '.' or '?' or '!'. If the character read was either of these, then the value 'truth' is set to one. Now, if the next character read was an alphabet, then it gets converted to upper case before being written to the other file, which is opened in write mode. Then, the value to 'truth' is set to zero. While the value of truth is set to zero, then the conversion from upper case to lower case does not take place.     
 
 copyright (c) 2015 K Sreram. You may not distribute this article without the concerned permission from K Sreram.  

About my blog


  

Featured post

Why increasing complexity is not good?

“ Simplicity is the ultimate sophistication.” — Leonardo da Vinci Why is complicating things wrong ? - K Sr...