UNIT 4
Structure And Unions
What is Structure?
Structure is a user-defined data type in C programming language that combines logically related data items of different data types together.
All the structure elements are stored at contiguous memory locations. Structure type variable can store more than one data item of varying data types under one name.
What is Union?
Union is a user-defined data type, just like a structure. Union combines objects of different types and sizes together. The union variable allocates the memory space equal to the space to hold the largest variable of union. It allows varying types of objects to share the same location.
Syntax of Declaring Structure
Struct [name of the structure]
{
Type member1;
Type member2;
Type member3;
};
Structure is declared using the "struct" keyword and name of structure. Number 1, number 2, number 3 are individual members of structure. The body part is terminated with a semicolon (;).
Example of Structure in C Programming
#include <stdio.h>
Struct student {
Char name[60];
Introll_no;
Float marks;
} sdt;
Int main() {
Printf("Enter the following information:\n");
Printf("Enter student name: ");
Fgets(sdt.name, sizeof(sdt.name), stdin);
Printf("Enter student roll number: ");
Scanf("%d", &sdt. Roll_no);
Printf("Enter students marks: ");
Scanf("%f", &sdt.marks);
Printf("The information you have entered is: \n");
Printf("Student name: ");
Printf("%s", sdt.name);
Printf("Student roll number: %d\n", sdt. Roll_no);
Printf("Student marks: %.1f\n", sdt.marks);
Return 0;
}
In the above program, a structure called student is created. This structure has three data members: 1) name (string), 2) roll_no (integer), and 3) marks (float).
After this, a structure variable sdt is created to store student information and display it on the computer screen.
Output:
Enter the following information:
Enter student name: James
Enter student roll number: 21
Enter student marks: 67
The information you have entered is:
Student name: John
Student roll number: 21
Student marks: 67.0
Syntax of Declaring Union
Union [name of union]
{
Type member1;
Type member2;
Type member3;
};
Union is declared using the "union" keyword and name of union. Number 1, number 2, number 3 are individual members of union. The body part is terminated with a semicolon (;).
Example of Union in C Programming
#include <stdio.h>
Union item
{
Int x;
Float y;
Charch;
};
Int main( )
{
Union item it;
It.x = 12;
It.y = 20.2;
It.ch = 'a';
Printf("%d\n", it.x);
Printf("%f\n", it.y);
Printf("%c\n", it.ch);
Return 0;
}
Output:
1101109601
20.199892
a
In the above program, you can see that the values of x and y gets corrupted. Only variable ch prints the expected result. It is because, in union, the memory location is shared among all member data types.
Therefore, the only data member whose value is currently stored, will occupy memory space. The value of the variable ch was stored at last, so the value of the rest of the variables is lost.
Structure vs. Union
Here is the important difference between structure and union:
Structure | Union |
You can use a struct keyword to define a structure. | You can use a union keyword to define a union. |
Every member within structure is assigned a unique memory location. | In union, a memory location is shared by all the data members. |
Changing the value of one data member will not affect other data members in structure. | Changing the value of one data member will change the value of other data members in union. |
It enables you to initialize several members at once. | It enables you to initialize only the first member of union. |
The total size of the structure is the sum of the size of every data member. | The total size of the union is the size of the largest data member. |
It is mainly used for storing various data types. | It is mainly used for storing one of the many data types that are available. |
It occupies space for each and every member written in inner parameters. | It occupies space for a member having the highest size written in inner parameters. |
You can retrieve any member at a time. | You can access one member at a time in the union. |
It supports flexible array. | It does not support a flexible array. |
Advantages of structure
Here are pros/benefits for using structure:
- Structures gather more than one piece of data about the same subject together in the same place.
- It is helpful when you want to gather the data of similar data types and parameters like first name, last name, etc.
- It is very easy to maintain as we can represent the whole record by using a single name.
- In structure, we can pass complete set of records to any function using a single parameter.
- You can use an array of structure to store more records with similar types.
Advantages of union
Here, are pros/benefits for using union:
- It occupies less memory compared to structure.
- When you use union, only the last variable can be directly accessed.
- Union is used when you have to use the same memory location for two or more data members.
- It enables you to hold data of only one data member.
- Its allocated space is equal to maximum size of the data member.
Disadvantages of structure
Here are cons/drawbacks for using structure:
- If the complexity of IT project goes beyond the limit, it becomes hard to manage.
- Change of one data structure in a code necessitates changes at many other places. Therefore, the changes become hard to track.
- Structure is slower because it requires storage space for all the data.
- You can retrieve any member at a time in structure whereas you can access one member at a time in the union.
- Structure occupies space for each and every member written in inner parameters while union occupies space for a member having the highest size written in inner parameters.
- Structure supports flexible array. Union does not support a flexible array.
Disadvantages of union
Here, are cons/drawbacks for using union:
- You can use only one union member at a time.
- All the union variables cannot be initialized or used with varying values at a time.
- Union assigns one common storage space for all its members.
KEY DIFFERENCES:
- Every member within structure is assigned a unique memory location while in union a memory location is shared by all the data members.
- Changing the value of one data member will not affect other data members in structure whereas changing the value of one data member will change the value of other data members in union.
- Structure is mainly used for storing various data types while union is mainly used for storing one of the many data types.
- In structure, you can retrieve any member at a time on the other hand in union, you can access one member at a time.
- Structure supports flexible array while union does not support a flexible array.
STRINGS
The string can be defined as the one-dimensional array of characters terminated by a null ('\0'). The character array or the string is used to manipulate text such as word or sentences. Each character in the array occupies one byte of memory, and the last character must always be 0. The termination character ('\0') is important in a string since it is the only way to identify where the string ends. When we define a string as char s[10], the character s[10] is implicitly initialized with the null in the memory.
There are two ways to declare a string in c language.
- By char array
- By string literal
Let's see the example of declaring string by char array in C language.
- Char ch[10]={'j', 'a', 'v', 'a', 't', 'p', 'o', 'i', 'n', 't', '\0'};
As we know, array index starts from 0, so it will be represented as in the figure given below.
While declaring string, size is not mandatory. So we can write the above code as given below:
- Char ch[]={'j', 'a', 'v', 'a', 't', 'p', 'o', 'i', 'n', 't', '\0'};
We can also define the string by the string literal in C language. For example:
- Char ch[]="javatpoint";
In such case, '\0' will be appended at the end of the string by the compiler.
Difference between char array and string literal
There are two main differences between char array and literal.
- We need to add the null character '\0' at the end of the array by ourselfwhereas, it is appended internally by the compiler in the case of the character array.
- The string literal cannot be reassigned to another set of characters whereas, we can reassign the characters of the array.
String Example in C
Let's see a simple example where a string is declared and being printed. The '%s' is used as a format specifier for the string in c language.
- #include<stdio.h>
- #include <string.h>
- Int main(){
- Char ch[11]={'j', 'a', 'v', 'a', 't', 'p', 'o', 'i', 'n', 't', '\0'};
- Char ch2[11]="javatpoint";
- Printf("Char Array Value is: %s\n", ch);
- Printf("String Literal Value is: %s\n", ch2);
- Return 0;
- }
Output
Char Array Value is: javatpoint
String Literal Value is: javatpoint
Traversing String
Traversing the string is one of the most important aspects in any of the programming languages. We may need to manipulate a very large text which can be done by traversing the text. Traversing string is somewhat different from the traversing an integer array. We need to know the length of the array to traverse an integer array, whereas we may use the null character in the case of string to identify the end the string and terminate the loop.
Hence, there are two ways to traverse a string.
- By using the length of string
- By using the null character.
Let's discuss each one of them.
Using the length of string
Let's see an example of counting the number of vowels in a string.
- #include<stdio.h>
- Void main ()
- {
- Char s[11] = "javatpoint";
- Int i = 0;
- Int count = 0;
- While(i<11)
- {
- If(s[i]=='a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'u' || s[i] == 'o')
- {
- Count ++;
- }
- i++;
- }
- Printf("The number of vowels %d",count);
- }
Output
The number of vowels 4
Using the null character
Let's see the same example of counting the number of vowels by using the null character.
- #include<stdio.h>
- Void main ()
- {
- Char s[11] = "javatpoint";
- Int i = 0;
- Int count = 0;
- While(s[i] != NULL)
- {
- If(s[i]=='a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'u' || s[i] == 'o')
- {
- Count ++;
- }
- i++;
- }
- Printf("The number of vowels %d",count);
- }
Output
The number of vowels 4
Accepting string as the input
Till now, we have used scanf to accept the input from the user. However, it can also be used in the case of strings but with a different scenario. Consider the below code which stores the string while space is encountered.
- #include<stdio.h>
- Void main ()
- {
- Char s[20];
- Printf("Enter the string?");
- Scanf("%s",s);
- Printf("You entered %s",s);
- }
Output
Enter the string?javatpoint is the best
You entered javatpoint
It is clear from the output that, the above code will not work for space separated strings. To make this code working for the space separated strings, the minor changed required in the scanf function, i.e., instead of writing scanf("%s",s), we must write: scanf("%[^\n]s",s) which instructs the compiler to store the string s while the new line (\n) is encountered. Let's consider the following example to store the space-separated strings.
- #include<stdio.h>
- Void main ()
- {
- Char s[20];
- Printf("Enter the string?");
- Scanf("%[^\n]s",s);
- Printf("You entered %s",s);
- }
Output
Enter the string?javatpoint is the best
You entered javatpoint is the best
Here we must also notice that we do not need to use address of (&) operator in scanf to store a string since string s is an array of characters and the name of the array, i.e., s indicates the base address of the string (character array) therefore we need not use & with it.
Some important points
However, there are the following points which must be noticed while entering the strings by using scanf.
- The compiler doesn't perform bounds checking on the character array. Hence, there can be a case where the length of the string can exceed the dimension of the character array which may always overwrite some important data.
- Instead of using scanf, we may use gets() which is an inbuilt function defined in a header file string.h. The gets() is capable of receiving only one string at a time.
Pointers with strings
We have used pointers with the array, functions, and primitive data types so far. However, pointers can be used to point to the strings. There are various advantages of using pointers to point strings. Let us consider the following example to access the string via the pointer.
- #include<stdio.h>
- Void main ()
- {
- Char s[11] = "javatpoint";
- Char *p = s; // pointer p is pointing to string s.
- Printf("%s",p); // the string javatpoint is printed if we print p.
- }
Output
Javatpoint
As we know that string is an array of characters, the pointers can be used in the same way they were used with arrays. In the above example, p is declared as a pointer to the array of characters s. P affects similar to s since s is the base address of the string and treated as a pointer internally. However, we can not change the content of s or copy the content of s into another string directly. For this purpose, we need to use the pointers to store the strings. In the following example, we have shown the use of pointers to copy the content of a string into another.
- #include<stdio.h>
- Void main ()
- {
- Char *p = "hello javatpoint";
- Printf("String p: %s\n",p);
- Char *q;
- Printf("copying the content of p into q...\n");
- q = p;
- Printf("String q: %s\n",q);
- }
Output
String p: hello javatpoint
Copying the content of p into q...
String q: hello javatpoint
Once a string is defined, it cannot be reassigned to another set of characters. However, using pointers, we can assign the set of characters to the string. Consider the following example.
- #include<stdio.h>
- Void main ()
- {
- Char *p = "hello javatpoint";
- Printf("Before assigning: %s\n",p);
- p = "hello";
- Printf("After assigning: %s\n",p);
- }
Output
Before assigning: hello javatpoint
After assigning: hello
STRING LIBRARY
The string.h header defines one variable type, one macro, and various functions for manipulating arrays of characters.
Library Variables
Following is the variable type defined in the header string.h−
Sr.No. | Variable & Description |
1 | Size_t This is the unsigned integral type and is the result of the sizeof keyword. |
Library Macros
Following is the macro defined in the header string.h−
Sr.No. | Macro & Description |
1 | NULL This macro is the value of a null pointer constant. |
Library Functions
Following are the functions defined in the header string.h−
Sr.No. | Function & Description |
1 | Void *memchr(const void *str, int c, size_t n) Searches for the first occurrence of the character c (an unsigned char) in the first n bytes of the string pointed to, by the argument str. |
2 | Intmemcmp(const void *str1, const void *str2, size_t n) Compares the first n bytes of str1 and str2. |
3 | Void *memcpy(void *dest, const void *src, size_t n) Copies n characters from src to dest. |
4 | Void *memmove(void *dest, const void *src, size_t n) Another function to copy n characters from str2 to str1. |
5 | Void *memset(void *str, int c, size_t n) Copies the character c (an unsigned char) to the first n characters of the string pointed to, by the argument str. |
6 | Char *strcat(char *dest, const char *src) Appends the string pointed to, by src to the end of the string pointed to by dest. |
7 | Char *strncat(char *dest, const char *src, size_t n) Appends the string pointed to, by src to the end of the string pointed to, by dest up to n characters long. |
8 | Char *strchr(const char *str, int c) Searches for the first occurrence of the character c (an unsigned char) in the string pointed to, by the argument str. |
9 | Intstrcmp(const char *str1, const char *str2) Compares the string pointed to, by str1 to the string pointed to by str2. |
10 | Intstrncmp(const char *str1, const char *str2, size_t n) Compares at most the first n bytes of str1 and str2. |
11 | Intstrcoll(const char *str1, const char *str2) Compares string str1 to str2. The result is dependent on the LC_COLLATE setting of the location. |
12 | Char *strcpy(char *dest, const char *src) Copies the string pointed to, by src to dest. |
13 | Char *strncpy(char *dest, const char *src, size_t n) Copies up to n characters from the string pointed to, by src to dest. |
14 | Size_tstrcspn(const char *str1, const char *str2) Calculates the length of the initial segment of str1 which consists entirely of characters not in str2. |
15 | Char *strerror(interrnum) Searches an internal array for the error number errnum and returns a pointer to an error message string. |
16 | Size_tstrlen(const char *str) Computes the length of the string str up to but not including the terminating null character. |
17 | Char *strpbrk(const char *str1, const char *str2) Finds the first character in the string str1 that matches any character specified in str2. |
18 | Char *strrchr(const char *str, int c) Searches for the last occurrence of the character c (an unsigned char) in the string pointed to by the argument str. |
19 | Size_tstrspn(const char *str1, const char *str2) Calculates the length of the initial segment of str1 which consists entirely of characters in str2. |
20 | Char *strstr(const char *haystack, const char *needle) Finds the first occurrence of the entire string needle (not including the terminating null character) which appears in the string haystack. |
21 | Char *strtok(char *str, const char *delim) Breaks string str into a series of tokens separated by delim. |
22 | Size_tstrxfrm(char *dest, const char *src, size_t n) Transforms the first n characters of the string src into current locale and places them in the string dest. |
In programming, we may require some specific input data to be generated several numbers of times. Sometimes, it is not enough to only display the data on the console. The data to be displayed may be very large, and only a limited amount of data can be displayed on the console, and since the memory is volatile, it is impossible to recover the programmatically generated data again and again. However, if we need to do so, we may store it onto the local file system which is volatile and can be accessed every time. Here, comes the need of file handling in C.
File handling in C enables us to create, update, read, and delete the files stored on the local file system through our C program. The following operations can be performed on a file.
- Creation of the new file
- Opening an existing file
- Reading from the file
- Writing to the file
- Deleting the file
Functions for file handling
There are many functions in the C library to open, read, write, search and close the file. A list of file functions are given below:
No. | Function | Description |
1 | Fopen() | Opens new or existing file |
2 | Fprintf() | Write data into the file |
3 | Fscanf() | Reads data from the file |
4 | Fputc() | Writes a character into the file |
5 | Fgetc() | Reads a character from file |
6 | Fclose() | Closes the file |
7 | Fseek() | Sets the file pointer to given position |
8 | Fputw() | Writes an integer to file |
9 | Fgetw() | Reads an integer from file |
10 | Ftell() | Returns current position |
11 | Rewind() | Sets the file pointer to the beginning of the file |
Opening File: fopen()
We must open a file before it can be read, write, or update. The fopen() function is used to open a file. The syntax of the fopen() is given below.
- FILE *fopen( const char * filename, const char * mode );
The fopen() function accepts two parameters:
- The file name (string). If the file is stored at some specific location, then we must mention the path at which the file is stored. For example, a file name can be like "c://some_folder/some_file.ext".
- The mode in which the file is to be opened. It is a string.
We can use one of the following modes in the fopen() function.
Mode | Description |
r | Opens a text file in read mode |
w | Opens a text file in write mode |
a | Opens a text file in append mode |
r+ | Opens a text file in read and write mode |
w+ | Opens a text file in read and write mode |
a+ | Opens a text file in read and write mode |
Rb | Opens a binary file in read mode |
Wb | Opens a binary file in write mode |
Ab | Opens a binary file in append mode |
Rb+ | Opens a binary file in read and write mode |
Wb+ | Opens a binary file in read and write mode |
Ab+ | Opens a binary file in read and write mode |
The fopen function works in the following way.
- Firstly, It searches the file to be opened.
- Then, it loads the file from the disk and place it into the buffer. The buffer is used to provide efficiency for the read operations.
- It sets up a character pointer which points to the first character of the file.
Consider the following example which opens a file in write mode.
- #include<stdio.h>
- Void main( )
- {
- FILE *fp ;
- Char ch ;
- Fp = fopen("file_handle.c","r") ;
- While ( 1 )
- {
- Ch = fgetc ( fp ) ;
- If ( ch == EOF )
- Break ;
- Printf("%c",ch) ;
- }
- Fclose (fp ) ;
- }
Output
The content of the file will be printed.
#include;
Void main( )
{
FILE *fp; // file pointer
Charch;
Fp = fopen("file_handle.c","r");
While ( 1 )
{
Ch = fgetc ( fp ); //Each character of the file is read and stored in the character file.
If ( ch == EOF )
Break;
Printf("%c",ch);
}
Fclose (fp );
}
Closing File: fclose()
The fclose() function is used to close a file. The file must be closed after performing all the operations on it. The syntax of fclose() function is given below:
- Int fclose( FILE *fp );
C fprintf() and fscanf()
Writing File :fprintf() function
The fprintf() function is used to write set of characters into file. It sends formatted output to a stream.
Syntax:
- Int fprintf(FILE *stream, const char *format [, argument, ...])
Example:
- #include <stdio.h>
- Main(){
- FILE *fp;
- Fp = fopen("file.txt", "w");//opening file
- Fprintf(fp, "Hello file by fprintf...\n");//writing data into file
- Fclose(fp);//closing file
- }
Reading File :fscanf() function
The fscanf() function is used to read set of characters from file. It reads a word from the file and returns EOF at the end of file.
Syntax:
- Int fscanf(FILE *stream, const char *format [, argument, ...])
Example:
- #include <stdio.h>
- Main(){
- FILE *fp;
- Char buff[255];//creating char array to store data of file
- Fp = fopen("file.txt", "r");
- While(fscanf(fp, "%s", buff)!=EOF){
- Printf("%s ", buff );
- }
- Fclose(fp);
- }
Output:
Hello file by fprintf...
C File Example: Storing employee information
Let's see a file handling example to store employee information as entered by user from console. We are going to store id, name and salary of the employee.
- #include <stdio.h>
- Void main()
- {
- FILE *fptr;
- Int id;
- Char name[30];
- Float salary;
- Fptr = fopen("emp.txt", "w+");/* open for writing */
- If (fptr == NULL)
- {
- Printf("File does not exists \n");
- Return;
- }
- Printf("Enter the id\n");
- Scanf("%d", &id);
- Fprintf(fptr, "Id= %d\n", id);
- Printf("Enter the name \n");
- Scanf("%s", name);
- Fprintf(fptr, "Name= %s\n", name);
- Printf("Enter the salary\n");
- Scanf("%f", &salary);
- Fprintf(fptr, "Salary= %.2f\n", salary);
- Fclose(fptr);
- }
Output:
Enter the id
1
Enter the name
Sonoo
Enter the salary
120000
Now open file from current directory. For windows operating system, go to TC\bin directory, you will see emp.txt file. It will have following information.
Emp.txt
Id= 1
Name= sonoo
Salary= 120000
C fputc() and fgetc()
Writing File :fputc() function
The fputc() function is used to write a single character into file. It outputs a character to a stream.
Syntax:
- Int fputc(int c, FILE *stream)
Example:
- #include <stdio.h>
- Main(){
- FILE *fp;
- Fp = fopen("file1.txt", "w");//opening file
- Fputc('a',fp);//writing single character into file
- Fclose(fp);//closing file
- }
File1.txt
a
Reading File :fgetc() function
The fgetc() function returns a single character from the file. It gets a character from the stream. It returns EOF at the end of file.
Syntax:
- Int fgetc(FILE *stream)
Example:
- #include<stdio.h>
- #include<conio.h>
- Void main(){
- FILE *fp;
- Char c;
- Clrscr();
- Fp=fopen("myfile.txt","r");
- While((c=fgetc(fp))!=EOF){
- Printf("%c",c);
- }
- Fclose(fp);
- Getch();
- }
Myfile.txt
This is simple text message
C fputs() and fgets()
The fputs() and fgets() in C programming are used to write and read string from stream. Let's see examples of writing and reading file using fgets() and fgets() functions.
Writing File :fputs() function
The fputs() function writes a line of characters into file. It outputs string to a stream.
Syntax:
- Int fputs(const char *s, FILE *stream)
Example:
- #include<stdio.h>
- #include<conio.h>
- Void main(){
- FILE *fp;
- Clrscr();
- Fp=fopen("myfile2.txt","w");
- Fputs("hello c programming",fp);
- Fclose(fp);
- Getch();
- }
Myfile2.txt
Hello c programming
Reading File :fgets() function
The fgets() function reads a line of characters from file. It gets string from a stream.
Syntax:
- Char* fgets(char *s, int n, FILE *stream)
Example:
- #include<stdio.h>
- #include<conio.h>
- Void main(){
- FILE *fp;
- Char text[300];
- Clrscr();
- Fp=fopen("myfile2.txt","r");
- Printf("%s",fgets(text,200,fp));
- Fclose(fp);
- Getch();
- }
Output:
Hello c programming
C fseek() function
The fseek() function is used to set the file pointer to the specified offset. It is used to write data into file at desired location.
Syntax:
- Int fseek(FILE *stream, long int offset, int whence)
There are 3 constants used in the fseek() function for whence: SEEK_SET, SEEK_CUR and SEEK_END.
Example:
- #include <stdio.h>
- Void main(){
- FILE *fp;
- Fp = fopen("myfile.txt","w+");
- Fputs("This is javatpoint", fp);
- Fseek( fp, 7, SEEK_SET );
- Fputs("sonoo jaiswal", fp);
- Fclose(fp);
- }
Myfile.txt
This is sonoojaiswal
A file represents a sequence of bytes, regardless of it being a text file or a binary file. C programming language provides access on high level functions as well as low level (OS level) calls to handle file on your storage devices. This chapter will take you through the important calls for file management.
Opening Files
You can use the fopen( ) function to create a new file or to open an existing file. This call will initialize an object of the type FILE, which contains all the information necessary to control the stream. The prototype of this function call is as follows −
FILE *fopen(const char * filename, const char * mode );
Here, filename is a string literal, which you will use to name your file, and access mode can have one of the following values −
Sr.No. | Mode & Description |
1 | R Opens an existing text file for reading purpose. |
2 | W Opens a text file for writing. If it does not exist, then a new file is created. Here your program will start writing content from the beginning of the file. |
3 | A Opens a text file for writing in appending mode. If it does not exist, then a new file is created. Here your program will start appending content in the existing file content. |
4 | r+ Opens a text file for both reading and writing. |
5 | w+ Opens a text file for both reading and writing. It first truncates the file to zero length if it exists, otherwise creates a file if it does not exist. |
6 | a+ Opens a text file for both reading and writing. It creates the file if it does not exist. The reading will start from the beginning but writing can only be appended. |
If you are going to handle binary files, then you will use following access modes instead of the above mentioned ones −
"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"
Closing a File
To close a file, use the fclose( ) function. The prototype of this function is −
Intfclose( FILE *fp );
The fclose(-) function returns zero on success, or EOF if there is an error in closing the file. This function actually flushes any data still pending in the buffer to the file, closes the file, and releases any memory used for the file. The EOF is a constant defined in the header file stdio.h.
There are various functions provided by C standard library to read and write a file, character by character, or in the form of a fixed length string.
Writing a File
Following is the simplest function to write individual characters to a stream −
Intfputc( int c, FILE *fp );
The function fputc() writes the character value of the argument c to the output stream referenced by fp. It returns the written character written on success otherwise EOF if there is an error. You can use the following functions to write a null-terminated string to a stream −
Intfputs( const char *s, FILE *fp );
The function fputs() writes the string s to the output stream referenced by fp. It returns a non-negative value on success, otherwise EOF is returned in case of any error. You can use intfprintf(FILE *fp,const char *format, ...) function as well to write a string into a file. Try the following example.
Make sure you have /tmp directory available. If it is not, then before proceeding, you must create this directory on your machine.
#include<stdio.h>
Main(){
FILE *fp;
Fp=fopen("/tmp/test.txt","w+");
Fprintf(fp,"This is testing for fprintf...\n");
Fputs("This is testing for fputs...\n",fp);
Fclose(fp);
}
When the above code is compiled and executed, it creates a new file test.txt in /tmp directory and writes two lines using two different functions. Let us read this file in the next section.
Reading a File
Given below is the simplest function to read a single character from a file −
Intfgetc( FILE * fp );
The fgetc() function reads a character from the input file referenced by fp. The return value is the character read, or in case of any error, it returns EOF. The following function allows to read a string from a stream −
Char *fgets( char *buf, int n, FILE *fp );
The functions fgets() reads up to n-1 characters from the input stream referenced by fp. It copies the read string into the buffer buf, appending a null character to terminate the string.
If this function encounters a newline character '\n' or the end of the file EOF before they have read the maximum number of characters, then it returns only the characters read up to that point including the new line character. You can also use intfscanf(FILE *fp, const char *format, ...) function to read strings from a file, but it stops reading after encountering the first space character.
#include<stdio.h>
Main(){
FILE *fp;
Char buff[255];
Fp=fopen("/tmp/test.txt","r");
Fscanf(fp,"%s", buff);
Printf("1 : %s\n", buff );
Fgets(buff,255,(FILE*)fp);
Printf("2: %s\n", buff );
Fgets(buff,255,(FILE*)fp);
Printf("3: %s\n", buff );
Fclose(fp);
}
When the above code is compiled and executed, it reads the file created in the previous section and produces the following result −
1 : This
2: is testing for fprintf...
3: This is testing for fputs...
Let's see a little more in detail about what happened here. First, fscanf() read just This because after that, it encountered a space, second call is for fgets() which reads the remaining line till it encountered end of line. Finally, the last call fgets() reads the second line completely.
Binary I/O Functions
There are two functions, that can be used for binary input and output −
Size_tfread(void*ptr,size_tsize_of_elements,size_tnumber_of_elements, FILE *a_file);
Size_tfwrite(constvoid*ptr,size_tsize_of_elements,size_tnumber_of_elements, FILE *a_file);
Both of these functions should be used to read or write blocks of memories - usually arrays or structures.
When we say Input, it means to feed some data into a program. An input can be given in the form of a file or from the command line. C programming provides a set of built-in functions to read the given input and feed it to the program as per requirement.
When we say Output, it means to display some data on screen, printer, or in any file. C programming provides a set of built-in functions to output the data on the computer screen as well as to save it in text or binary files.
The Standard Files
C programming treats all the devices as files. So devices such as the display are addressed in the same way as files and the following three files are automatically opened when a program executes to provide access to the keyboard and screen.
Standard File | File Pointer | Device |
Standard input | Stdin | Keyboard |
Standard output | Stdout | Screen |
Standard error | Stderr | Your screen |
The file pointers are the means to access the file for reading and writing purpose. This section explains how to read values from the screen and how to print the result on the screen.
The getchar() and putchar() Functions
The intgetchar(void) function reads the next available character from the screen and returns it as an integer. This function reads only single character at a time. You can use this method in the loop in case you want to read more than one character from the screen.
The intputchar(int c) function puts the passed character on the screen and returns the same character. This function puts only single character at a time. You can use this method in the loop in case you want to display more than one character on the screen. Check the following example −
#include<stdio.h>
Int main(){
Int c;
Printf("Enter a value :");
c =getchar();
Printf("\nYou entered: ");
Putchar( c );
Return0;
}
When the above code is compiled and executed, it waits for you to input some text. When you enter a text and press enter, then the program proceeds and reads only a single character and displays it as follows −
$./a.out
Enter a value : this is test
You entered: t
The gets() and puts() Functions
The char *gets(char *s) function reads a line from stdin into the buffer pointed to by s until either a terminating newline or EOF (End of File).
The intputs(const char *s) function writes the string 's' and 'a' trailing newline to stdout.
NOTE: Though it has been deprecated to use gets() function, Instead of using gets, you want to use fgets().
#include<stdio.h>
Int main(){
Charstr[100];
Printf("Enter a value :");
Gets(str);
Printf("\nYou entered: ");
Puts(str);
Return0;
}
When the above code is compiled and executed, it waits for you to input some text. When you enter a text and press enter, then the program proceeds and reads the complete line till end, and displays it as follows −
$./a.out
Enter a value : this is test
You entered: this is test
The scanf() and printf() Functions
The intscanf(const char *format, ...) function reads the input from the standard input stream stdin and scans that input according to the format provided.
The intprintf(const char *format, ...) function writes the output to the standard output stream stdout and produces the output according to the format provided.
The format can be a simple constant string, but you can specify %s, %d, %c, %f, etc., to print or read strings, integer, character or float respectively. There are many other formatting options available which can be used based on requirements. Let us now proceed with a simple example to understand the concepts better −
#include<stdio.h>
Int main(){
Charstr[100];
Inti;
Printf("Enter a value :");
Scanf("%s %d",str,&i);
Printf("\nYou entered: %s %d ",str,i);
Return0;
}
When the above code is compiled and executed, it waits for you to input some text. When you enter a text and press enter, then program proceeds and reads the input and displays it as follows −
$./a.out
Enter a value : seven 7
You entered: seven 7
Here, it should be noted that scanf() expects input in the same format as you provided %s and %d, which means you have to provide valid inputs like "string integer". If you provide "string string" or "integer integer", then it will be assumed as wrong input. Secondly, while reading a string, scanf() stops reading as soon as it encounters a space, so "this is test" are three strings for scanf().
C Output
In C programming, printf() is one of the main output function. The function sends formatted output to the screen. For example,
Example 1: C Output
Intmain()
{
// Displays the string inside quotations
Printf("C Programming");
Return0;
}
Output
C Programming
How does this program work?
- All valid C programs must contain the main() function. The code execution begins from the start of the main() function.
- The printf() is a library function to send formatted output to the screen. The function prints the string inside quotations.
- To use printf() in our program, we need to include stdio.h header file using the #include <stdio.h> statement.
- The return 0; statement inside the main() function is the "Exit status" of the program. It's optional.
Example 2: Integer Output
Intmain()
{
InttestInteger = 5;
Printf("Number = %d", testInteger);
Return0;
}
Output
Number = 5
We use %d format specifier to print int types. Here, the %d inside the quotations will be replaced by the value of testInteger.
Example 3: float and double Output
Intmain()
{
Float number1 = 13.5;
Double number2 = 12.4;
Printf("number1 = %f\n", number1);
Printf("number2 = %lf", number2);
Return0;
}
Output
Number1 = 13.500000
Number2 = 12.400000
To print float, we use %f format specifier. Similarly, we use %lf to print double values.
Example 4: Print Characters
Intmain()
{
Charchr = 'a';
Printf("character = %c", chr);
Return0;
}
Output
Character = a
To print char, we use %c format specifier.
C Input
In C programming, scanf() is one of the commonly used function to take input from the user. The scanf() function reads formatted input from the standard input such as keyboards.
Example 5: Integer Input/Output
Intmain()
{
InttestInteger;
Printf("Enter an integer: ");
Scanf("%d", &testInteger);
Printf("Number = %d",testInteger);
Return0;
}
Output
Enter an integer: 4
Number = 4
Here, we have used %d format specifier inside the scanf() function to take int input from the user. When the user enters an integer, it is stored in the testInteger variable.
Notice, that we have used &testInteger inside scanf(). It is because &testInteger gets the address of testInteger, and the value entered by the user is stored in that address.
Example 6: Float and Double Input/Output
Intmain()
{
Float num1;
Double num2;
Printf("Enter a number: ");
Scanf("%f", &num1);
Printf("Enter another number: ");
Scanf("%lf", &num2);
Printf("num1 = %f\n", num1);
Printf("num2 = %lf", num2);
Return0;
}
Output
Enter a number: 12.523
Enter another number: 10.2
Num1 = 12.523000
Num2 = 10.200000
We use %f and %lf format specifier for float and double respectively.
Example 7: C Character I/O
Intmain()
{
Charchr;
Printf("Enter a character: ");
Scanf("%c",&chr);
Printf("You entered %c.", chr);
Return0;
}
Output
Enter a character: g
You entered g
When a character is entered by the user in the above program, the character itself is not stored. Instead, an integer value (ASCII value) is stored.
And when we display that value using %c text format, the entered character is displayed. If we use %d to display the character, it's ASCII value is printed.
Example 8: ASCII Value
Intmain()
{
Charchr;
Printf("Enter a character: ");
Scanf("%c", &chr);
// When %c is used, a character is displayed
Printf("You entered %c.\n",chr);
// When %d is used, ASCII value is displayed
Printf("ASCII value is %d.", chr);
Return0;
}
Output
Enter a character: g
You entered g.
ASCII value is 103.
I/O Multiple Values
Here's how you can take multiple inputs from the user and display them.
Intmain()
{
Int a;
Float b;
Printf("Enter integer and then a float: ");
// Taking multiple inputs
Scanf("%d%f", &a, &b);
Printf("You entered %d and %f", a, b);
Return0;
}
Output
Enter integer and then a float: -3
3.4
You entered -3 and 3.400000
Format Specifiers for I/O
As you can see from the above examples, we use
- %d for int
- %f for float
- %lf for double
- %c for char
Here's a list of commonly used C data types and their format specifiers.
Data Type | Format Specifier |
Int | %d |
Char | %c |
Float | %f |
Double | %lf |
Short int | %hd |
Unsigned int | %u |
Long int | %li |
Long longint | %lli |
Unsigned long int | %lu |
Unsigned long longint | %llu |
Signed char | %c |
Unsigned char | %c |
Long double | %Lf |
Concepts
- I/O is essentially done one character (or byte) at a time
- Stream -- a sequence of characters flowing from one place to another
- Input stream: data flows from input device (keyboard, file, etc) into memory
- Output stream: data flows from memory to output device (monitor, file, printer, etc)
- Standard I/O streams (with built-in meaning)
- Stdin: standard input stream (default is keyboard)
- Stdout: standard output stream (defaults to monitor)
- Stderr: standard error stream
- Stdio.h -- contains basic I/O functions
- Scanf: reads from standard input (stdin)
- Printf: writes to standard output (stdout)
- There are other functions similar to printf and scanf that write to and read from other streams
- How to include, for C or C++ compiler
- #include <stdio.h> // for a C compiler
- #include <cstdio> // for a C++ compiler
- Formatted I/O -- refers to the conversion of data to and from a stream of characters, for printing (or reading) in plain text format
- All text I/O we do is considered formatted I/O
- The other option is reading/writing direct binary information (common with file I/O, for example)
Output with printf
Recap
- The basic format of a printf function call is:
- Printf (format_string, list_of_expressions);
Where:
- Format_string is the layout of what's being printed
- List_of_expressions is a comma-separated list of variables or expressions yielding results to be inserted into the output
- To output string literals, just use one parameter on printf, the string itself
- Printf("Hello, world!\n");
- Printf("Greetings, Earthling\n\n");
Conversion Specifiers
A conversion specifier is a symbol that is used as a placeholder in a formatting string. For integer output (for example), %d is the specifier that holds the place for integers.
Here are some commonly used conversion specifiers (not a comprehensive list):
%d int (signed decimal integer)
%u unsigned decimal integer
%f floating point values (fixed notation) - float, double
%e floating point values (exponential notation)
%s string
%c character
Printing Integers
- To output an integer, use %d in the format string, and an integer expression in the list_of_expressions.
- IntnumStudents = 35123;
- Printf("FSU has %d students", numStudents);
- // Output:
- // FSU has 35123 students
- We can specify the field wicth (i.e. how many 'spaces' the item prints in). Defaults to right-justification. Place a number between the % and the d. In this example, field width is 10:
- Printf("FSU has %10d students", numStudents);
- // Output:
- // FSU has 35123 students
- To left justify, use a negative number in the field width:
- Printf("FSU has %-10d students", numStudents);
- // Output:
- // FSU has 35123 students
- If the field width is too small or left unspecified, it defaults to the minimum number of characters required to print the item:
- Printf("FSU has %2d students", numStudents);
- // Output:
- // FSU has 35123 students
- Specifying the field width is most useful when printing multiple lines of output that are meant to line up in a table format
Printing Floating-point numbers
- Use the %fmodifer to print floating point values in fixed notation:
- Double cost = 123.45;
- Printf("Your total is $%f today\n", cost);
- // Output:
- // Your total is $123.450000 today
- Use %e for exponential notation:
- Printf("Your total is $%e today\n", cost);
- // Output:
- // Your total is $1.234500e+02 today
Note that the e+02 means "times 10 to the 2nd power"
- You can also control the decimal precision, which is the number of places after the decimal. Output will round to the appropriate number of decimal places, if necessary:
- Printf("Your total is $%.2f today\n", cost);
- // Output:
- // Your total is $123.45 today
- Field width can also be controlled, as with integers:
- Printf("Your total is $%9.2f today\n", cost);
- // Output:
- // Your total is $ 123.45 today
In the conversion specifier, the number before the decimal is field width, and the number after is the precision. (In this example, 9 and 2).
- %-9.2 would left-justify in a field width of 9, as with integers
Printing characters and strings
- Use the formatting specifier %c for characters. Default field size is 1 character:
- Char letter = 'Q';
- Printf("%c%c%c\n", '*', letter, '*');
- // Output is: *Q*
- Use %s for printing strings. Field widths work just like with integers:
- Printf("%s%10s%-10sEND\n", "Hello", "Alice", "Bob");
- // Output:
- // Hello AliceBob END
Scanf
Basics
- To read data in from standard input (keyboard), we call the scanf function. The basic form of a call to scanf is:
- Scanf(format_string, list_of_variable_addresses);
- The format string is like that of printf
- But instead of expressions, we need space to store incoming data, hence the list of variable addresses
- If x is a variable, then the expression &x means "address of x"
- Scanf example:
- Int month, day;
- Printf("Please enter your birth month, followed by the day: ");
- Scanf("%d %d", &month, &day);
- Conversion Specifiers
- Mostly the same as for output. Some small differences
- Use %f for type float, but use %lf for types double and long double
- The data type read, the conversion specifier, and the variable used need to match in type
- White space is skipped by default in consecutive numeric reads. But it is not skipped for character/string inputs.
Example
#include <stdio.h>
Int main()
{
Inti;
Float f;
Char c;
Printf("Enter an integer and a float, then Y or N\n> ");
Scanf("%d%f%c", &i, &f, &c);
Printf("You entered:\n");
Printf("i = %d, f = %f, c = %c\n", i, f, c);
}
Sample run #1
User input underlined, to distinguish it from program output
Enter an integer and a float, then Y or N
>34 45.6Y
You entered:
i = 34, f = 45.600, c = Y
Sample Run #2
Enter an integer and a float, then Y or N
>12 34.5678 N
You entered:
i = 12, f = 34.568, c =
Note that in this sample run, the character that was read was NOT the letter 'N'. It was the space. (Remember, white space not skipped on character reads).
This can be accounted for. Consider if the scanf line looked like this:
Scanf("%d%f %c", &i, &f, &c);
There's a space betwen the %f and the %c in the format string. This allows the user to type a space. Suppose this is the typed input:
12 34.5678 N
Then the character variable c will now contain the 'N'.
Interactive Input
You can make input more interactive by prompting the user more carefully. This can be tedious in some places, but in many occasions, it makes programs more user-friendly. Example:
Int age;
Doublegpa;
Char answer;
Printf("Please enter your age: ");
Scanf("%d", &age);
Printf("Please enter your gpa: ");
Scanf("%lf", %gpa);
Printf("Do you like pie (Y/N)? ");
Scanf("%c", %answer);
A good way to learn more about scanf is to try various inputs in various combinations, and type in test cases -- see what happens!
Printf/scanf with C-strings
An entire C-style string can be easily printed, by using the %s formatting symbol, along with the name of the char array storing the string (as the argument filling in that position):
Char greeting[] = "Hello";
Printf("%s", greeting); // prints the word "Hello"
Be careful to only use this on char arrays that are being used as C-style strings. (This means, only if the null character is present as a terminator).
Similarly, you can read a string into a char array with scanf. The following call allows the entry of a word (up to 19 characters and a terminating null character) from the keyboard, which is stored in the array word1:
Char word1[20];
Scanf("%s", word1);
Characters are read from the keyboard until the first "white space" (space, tab, newline) character is encountered. The input is stored in the character array and the null character is automatically appended.
Note also that the & was not needed in the scanf call (word1 was used, instead of &word1). This is because the name of the array by itself (with no index) actually IS a variable that stores an address (a pointer).
It is useful to store the block of data into the file rather than individual elements.Each block has some fixed size,it may be of strcture or of an array.It is possible that a data file has one or more structures or arrays,So it is easy to read the entire block from file or write the entire block to the file.There are two useful functions for this purpose
1. Fwrite():
This function is used for writing an entire block to a given file.
Syntax: fwrite(ptr, size, nst, fptr);
Where ptr is a pointer which points to the arrayofstruture in which data is written.
Size is the size of the structure
nst is the number of the structure
fptr is a filepointer.
Example program for fwrite():
Write a program to read an employee details and write them into the file at a time using fwrite().
01 | #include<stdio.h> |
02 | #include<conio.h> |
03 | Voidmain() | |
04 | { | |
05 | Structemp | |
06 | { | |
07 | Inteno; | |
08 | Charename[20]; | |
09 | Floatsal; | |
10 | }e; | |
11 | FILE *fp; | |
12 | Fp=fopen("emp.dat", "wb"); | |
13 | Clrscr(); | |
14 | Printf("Enter employee number"); | |
15 | Scanf("&d",&e.eno); | |
16 | Printf("Enter employee name"); | |
17 | Fflush(stdin); | |
18 | Scanf("%s",e.ename); | |
19 | Printf("Enter employee salary"); | |
20 | Scanf("%f",&e.sal); | |
21 | Fwrite(&e,sizeof(e),1,fp); | |
22 | Printf("One record stored successfully"); | |
23 | Getch(); | |
24 | } | |
OUTPUT:
Enter employee num: 10
Enter employee name : seshu
Enter employee salary : 10000
One record stored successfully.
2. Fread():
This function is used to read an entire block from a given file.
Syntax:fread( ptr , size , nst , fptr);
Where ptr is a pointer which points to the array which receives structure.
Size is the size of the structure
nst is the number of the structure
fptr is a filepointer.
Example program for fread():
Write a program to read an employee details at a time from a file using fread() which are written above using fwrite()and display them on the output screen.
01 | #include<stdio.h> |
02 | #include<conio.h> |
03 | Voidmain() | |
04 | { | |
05 | Structemp | |
06 | { | |
07 | Inteno; | |
08 | Charename[20]; | |
09 | Floatsal; | |
10 | }e; | |
11 | FILE *fp; | |
12 | Fp=fopen("emp.dat", "rb"); | |
13 | Clrscr(); | |
14 | If(fp==NULL) | |
15 | Printf("File cannot be opened"); | |
16 | Else | |
17 | Fread(&e,sizeof(e),1,fp); | |
18 | Printf("\nEmployee number is %d",e.eno); | |
19 | Printf("\nEmployee name is %s",e.ename); |
20 | Printf("\nEmployee salary is %f",e.sal); |
21 | Printf("One record read successfully"); | |
22 | Getch(); | |
23 | } |
OUTPUT:
Employee number is 10
Employee name is seshu
Employee salary is 10000.
One record read successfully.
fprintf ()
This function is same as the printf() function but it writes the data into the file, so it has one more parameter that is the file pointer.
Syntax:fprintf(fptr, "controlcharacter",variable-names);
Where fptr is a file pointer
Control character specifies the type of data to be printed into file.
Variable-names hold the data to be printed into the file.
fscanf ()
This function is same as the scanf() function but this reads the data from the file, so this has one more parameter that is the file pointer.
Syntax:fscanf(fptr, "control character", &variable-names);
Where fptr is a file pointer
Control character specifies the type of data to be read from the file.
Address of Variable names are those that hold the data read from the file.
Example for fprintf() and fscanf()
Write a program to read details of an employee and print them in a file using fprintf() and read the same from the file using fscanf() and display on the output screen.
01 | #include<stdio.h> |
02 | #include<conio.h> |
03 | Voidmain() | |
04 | { | |
05 | FILE*fp; | |
06 | Inteno; | |
07 | Charename[20]; | |
08 | Floatsal; | |
09 | Clrscr(); | |
10 | Fp=fopen("emp.dat", "w+"); | |
11 | Printf("Enter employee number"); | |
12 | Scanf("&d",eno); | |
13 | Printf("Enter employee name"); | |
14 | Fflush(stdin); | |
15 | Scanf("%s",ename); | |
16 | Printf("Enter employee salary"); | |
17 | Scanf("%f",sal); | |
18 | Fprintf(fp, "%d %s %f\n",eno,ename,sal); | |
19 | Printf("Details of an employee are printed into file"); | |
20 | Rewind(fp); | |
21 | Fscanf(fp,"%d %s %f",&eno,ename,&esal); | |
22 | Printf("Details of employee are\n"); | |
23 | Printf("\n %d %s %f", eno,ename, sal); | |
24 | Fclose(fp); | |
25 | Getch(); | |
26 | } | |
OUTPUT:
Enter employee num: 10
Enter employee name : seshu
Enter employee salary : 10000
Details of an employee are printed into file.
Details of employee are
Employee number is 10
Employee name is seshu
Employee salary is 10000.
feof()
The macro feof() is used for detecting whether the file pointer is at the end of file or not.It returns nonzero if the file pointer is at the end of the file otherwise it returns zero.
Syntax:feof(fptr);
Where fptr is a file pointer .
ferror()
The macro ferror() is used for detecting whether an error occur in the file on filepointer or not.It returns the value nonzero if an error,otherwise it returns zero.
Syntax:ferror(fptr);
Where fptr is a file pointer.
When we are talking about sequential or random access to data files we refer to the way data is written or read from a file on a computer system.
Sequential Access to a data file means that the computer system reads or writes information to the file sequentially, starting from the beginning of the file and proceeding step by step.
On the other hand, Random Access to a file means that the computer system can read or write information anywhere in the data file. This type of operation is also called “Direct Access” because the computer system knows where the data is stored (using Indexing) and hence goes “directly” and reads the data.
Sequential access has advantages when you access information in the same order all the time. Also is faster than random access.
On the other hand, random access file has the advantage that you can search through it and find the data you need more easily (using indexing for example). Random Access Memory (RAM) in computers works like that.
Description
The C library function intfseek(FILE *stream, long int offset, int whence) sets the file position of the stream to the given offset.
Declaration
Following is the declaration for fseek() function.
Intfseek(FILE *stream, long int offset, int whence)
Parameters
- Stream− This is the pointer to a FILE object that identifies the stream.
- Offset− This is the number of bytes to offset from whence.
- Whence− This is the position from where offset is added. It is specified by one of the following constants −
Sr.No. | Constant & Description |
1 | SEEK_SET Beginning of file |
2 | SEEK_CUR Current position of the file pointer |
3 | SEEK_END End of file |
Return Value
This function returns zero if successful, or else it returns a non-zero value.
Example
The following example shows the usage of fseek() function.
#include <stdio.h>
Int main () {
FILE *fp;
Fp = fopen("file.txt","w+");
Fputs("This is tutorialspoint.com", fp);
Fseek(fp, 7, SEEK_SET );
Fputs(" C Programming Language", fp);
Fclose(fp);
Return(0);
}
Let us compile and run the above program that will create a file file.txt with the following content. Initially program creates the file and writes This is tutorialspoint.com but later we had reset the write pointer at 7th position from the beginning and used puts() statement which over-write the file with the following content −
This is C Programming Language
Now let's see the content of the above file using the following program −
#include <stdio.h>
Int main () {
FILE *fp;
Int c;
Fp = fopen("file.txt","r");
While(1) {
c = fgetc(fp);
If(feof(fp) ) {
Break;
}
Printf("%c", c);
}
Fclose(fp);
Return(0);
}
Let us compile and run the above program to produce the following result −
This is C Programming Language
Text Books:
[T1] Herbert Schildt, ―C: The Complete Reference‖, OsbourneMcgraw Hill, 4th Edition, 2002.
[T2] Forouzan Behrouz A. ―Computer Science: A Structured Programming Approach Using C, Cengage Learning 2/e
Reference Books:
[R1] Kernighan & Ritchie, ―C Programming Language‖, The (Ansi C version), PHI, 2/e
[R2] K.R Venugopal, ―Mastering C ‖, TMH
[R3] R.S. Salaria "Application Programming in C " Khanna Publishers4/e
[R4] YashwantKanetkar― Test your C Skills ‖ , BPB Publications
[R5] http://www.codeblocks.org/
[R6] http://gcc.gnu.org/
[R7] Programming in ANSI C, E. Balagurusamy; Mc Graw Hill, 6th Edition.