Topic : Introduction to C Programming
Author : Mkoubaa
Page : << Previous 6  Next >>
Go to page :


text file directly. For example, you might need to open a specific file name and read from or write to it. You might want to manage several streams of input or output or create a program like a text editor that can save and recall data or configuration files on command.

fopen   opens a text file
fclose  closes a text file
feof    detects end-of-file marker in a file
fprintf prints formatted output to a file
fscanf  reads formatted input from a file
fputs   prints a string to a file
fgets   reads a string from a file
fputc   prints a character to a file
fgetc   reads a character from a file

You use fopen like reset and rewrite in Pascal. It opens a file for a specified mode (the three most common are r, w, and a, for read, write, and append). It then returns a file pointer that you use to access the file. For example, suppose you want to open a file and write the numbers 1 to 10 in it. You could use the following code:

#include <stdio.h>
#define MAX 10
void main()  
{    
    FILE *f;    
    int x;
     f=fopen("out","w");    
    for(x=1; x<=MAX; x++)      
        fprintf(f,"%d\n",x);
    fclose(f);
}


The fopen statement here opens a file named out with the w mode. This is a destructive write mode, which means that if out does not exist it is created, but if it does exist it is destroyed and a new file is created in its place. The fopen command returns a pointer to the file, which is stored in the variable f. This variable is used to refer to the file. If the file cannot be opened for some reason, f will contain NULL.
The fprintf statement should look very familiar: It is just like printf but uses the file pointer as its first parameter. The fclose statement closes the file when you are done.
To read a file, open it with r mode. In general, it is not a good idea to use fscanf for reading: Unless the file is perfectly formatted, fscanf will not handle it correctly. Instead, use fgets to read in each line and then parse out the pieces you need.
The following code demonstrates the process of reading a file and dumping its contents to the screen:

#include <stdio.h>

void main()  
{    
    FILE *f;    
    char s[1000];
    
    f=fopen("infile","r");    
    while (fgets(s,1000,f)!=NULL)      
        printf("%s",s);    
    fclose(f);  
}


The fgets statement returns a NULL value at the end-of-file marker. It reads a line (up to 1,000 characters in this case) and then prints it to stdout. Notice that the printf statement does not include \n in the format string, because fgets adds \n to the end of each line it reads. Thus, you can tell if a line is not complete in the event that it overflows the maximum line length specified in the second parameter to fgets.
C Errors to Avoid:
Do not accidentally type close instead of fclose . The close function exists, so the compiler accepts it. It will even appear to work if the program only opens or closes a few files. However, if the program opens and closes a file in a loop, it will eventually run out of available file handles and/or memory space and crash, because close is not closing the files correctly.

Introduction to C Programming
Part 9: Introduction to Pointers in C


Pointers are used everywhere in C, and if you have a good understanding of them C should not pose a problem. If, however, you have never seen pointers before, or feel uncomfortable with them, you may want to read an extra book or two, or talk to someone who already understands them. C pointers are basically the same as Pascal pointers except they are used much more freely in C.
C uses pointers in three main ways. First, they are used to create dynamic data structures: data structures built up from blocks of memory allocated from the heap at run-time. This is the only visible way that Pascal uses pointers. Second, C uses pointers to handle variable parameters passed to functions. And third, pointers in C provide an alternative means of accessing information stored in arrays, which is especially valuable when you work with strings (see tutorial 13). There is an intimate link between arrays and pointers in C.
In many cases, C programmers use pointers because they make the code slightly more efficient. Sometimes, however, they simply seem to make the code harder to understand. Once you have mastered the three uses of pointers in C, however, you "know" C for all practical purposes.
Pointer Basics
A normal variable is a location in memory that can hold a value. For example, when you declare a variable i as an integer, four bytes of memory are set aside for it. In your program, you refer to that location in memory by the name i. At the machine level, that location has a memory address, at which the four bytes can hold one integer value.
A pointer is a variable that points to another variable. This means that it holds the memory address of another variable. Put another way, the pointer does not hold a value in the traditional sense; instead, it holds the address of another variable. It points to that other variable by holding its address.
Because a pointer holds an address rather than a value, it has two parts. The pointer itself holds the address. That address points to a value. There is the pointer and the value pointed to. This fact can be a little confusing until you get used to it.
The following example code shows a typical pointer:

#include <stdio.h>

void main()  
{    
    int i,j;    
    int *p;   /* a pointer to an integer */
     p = &i;    
    *p=5;    
    j=i;    
    printf("%d %d %d\n",i,j,*p);  
}


The line int *p declares a pointer. It asks the compiler to declare a variable p that is a pointer to an integer. The * indicates that a pointer is being declared rather than a normal variable. You can create a pointer to anything: a float, a structure, a char, and so on.
The line p = &i; will definitely be new to you. In C, & is called the address operator. The expression &i means ``the memory address of the variable i ." Thus, the expression p = &i; means "Assign to p the address of i." Once you execute this statement, p points to i. Before you do so, p contains a random, unknown address, and its use will likely cause a segmentation fault.
After the line p = &I;, p points to I. Once p points to i, the memory location i has two names. It is still known as i, but now it is known as *p as well. This is how C talks about the two parts of a pointer variable: p is the location holding the address, while *p is the location pointed to by that address. Therefore *p=5 means that the location pointed to by p should be set to 5. Because this location is also i, i also takes on the value 5. Consequently, j=i; sets j to 5, and the printf statement produces 5 5 5.
Try the following:

#include <stdio.h>

void main()  
{    
    int i,j;    
    int *p;   /* a pointer to an integer */
     printf("%d %d\n",p,&i);    
    p = &i;    
    printf("%d %d\n",p,&i);  
}


This code tells the compiler to print out the address held in p, along with the address of i. The variable p starts off with some crazy value or with 0. The address of i is generally a large value. For example, when I ran this code, I received the following output:

0   2147478276
2147478276   2147478276

which means that the address of i is 2147478276. Once the statement p = &i; has been executed, p contains the address of i. Try this as well:

#include <stdio.h>
  
void main()  
{    
  


Page : << Previous 6  Next >>