C Programming For Problem Solving Module 5
C Programming For Problem Solving Module 5
Structure in C
Structure:
The structure in C is a user-defined data type that can group items of potentially different types into a single type. The struct keyword is used to
define the structure in the C programming language. The items within the structure are called its members, and they can be of any valid data type.
Furthermore, the values of a structure are stored in contiguous memory locations.
Structures must be declared in C before being used in a program. In a structure declaration, member variables and their data types are specified. The
struct keyword is used to declare a structure using the following syntax:
struct structure_name
{
data_type member_name1;
data_type member_name2;
...
};
This syntax is known as a structure template or structure prototype. Note that no memory is allocated to the structure at the point of declaration. For
practical applications and a deeper understanding of how structures build complex data structures, the C Programming Course Online with Data
Structures is recommended.
To use a structure in a program, an instance of it must be defined by creating variables of the structure type. There are two ways to define structure
variables:
150
CHAPTER 5. STRUCTURE IN C 151
...
} variable1, variable2, ...;
structure_name.member1;
structure_name.member2;
If a pointer to the structure is used, the arrow operator (->) can be employed to access the members.
Structure members cannot be initialized at the time of declaration. For instance, the following code will result in a compiler error:
struct Point {
int x = 0; // COMPILER ERROR
int y = 0; // COMPILER ERROR
};
The error arises because no memory is allocated when a datatype is declared, only when variables are created.
By default, structure members are not automatically initialized to zero or NULL. Uninitialized members will contain garbage values. However, when a
structure variable is declared with an initializer, uninitialized members are zero-initialized:
struct Point {
int x;
int y;
};
struct Point p = {0}; // Both x and y are initialized to 0
The typedef keyword allows defining an alias for an existing datatype. This can simplify the code by reducing the need to repeatedly use the struct
keyword:
typedef struct {
int a;
} str1;
typedef struct {
int x;
} str2;
5.4.1 Example
#include <stdio.h>
typedef struct {
int a;
} str1;
typedef struct {
int x;
} str2;
int main() {
str1 var1 = { 20 };
str2 var2 = { 314 };
return 0;
}
Output:
var1.a = 20
var2.x = 314
C allows structures to be nested within other structures, called nested structures. There are two types of nested structures:
struct parent {
int member1;
struct {
int member_str1;
char member_str2;
} member2;
};
struct member_str {
int member_str1;
char member_str2;
};
struct parent {
int member1;
struct member_str member2;
};
str_parent.str_child.member;
A pointer to a structure can be defined and used to access structure members using the arrow operator (->):
#include <stdio.h>
struct Point {
int x, y;
};
int main() {
struct Point str = { 1, 2 };
struct Point* ptr = &str;
return 0;
}
Output:
1 2
Self-referential structures contain a pointer to the same structure type. These are used in linked lists, trees, etc.:
struct structure_name {
data_type member1;
struct structure_name* str;
};
In C, the dot (.) operator is used to access members of user-defined data types such as a structure or union. Also known as the direct member access
operator, it allows us to access the data of the struct and union via the name of variables.
#include <stdio.h>
CHAPTER 5. STRUCTURE IN C 154
struct A {
int x;
};
int main() {
struct A a = {30};
return 0;
}
Output
30
Explanation: In the above code, a.x accesses the x member of the a structure. The dot operator is used to retrieve or modify values stored in these
members of the structure.
name . member;
where,
The dot operator can also be used to access the members of nested structures and unions. It can be done in the same way as done for the normal
structure.
The dot (.) operator has the highest operator precedence in C Language and its associativity is from left to right.
Note: dot (.) operator can only be used with structures or unions in C language.
#include <stdio.h>
union A {
int x;
char c;
};
int main() {
union A a;
return 0;
}
Output
10
Z
#include <stdio.h>
struct Base {
struct Child {
int i;
} child;
};
int main() {
struct Base base = { 12 };
Output
12
5.9 typedef
The typedef is a keyword that is used to provide existing data types with a new name. The C typedef keyword is used to redefine the name of already
existing data types. When names of datatypes become difficult to use in programs, typedef is used with user-defined datatypes, which behave similarly
to defining an alias for commands.
Example
#include <stdio.h>
int main() {
// n is of type int, but we are using alias Integer
Integer n = 10;
printf("%d", n);
return 0;
}
Output:
10
Explanation: Here, the typedef creates an alias Integer for the int type. This allows us to use Integer instead of int throughout the program,
making the code potentially more readable.
CHAPTER 5. STRUCTURE IN C 156
Syntax of typedef
• existing_type: The type that we want to alias (e.g., int, float, struct, etc.).
After this declaration, we can use the alias as if it were the real existing type in our C program.
Examples of typedef in C
#include <stdio.h>
int main() {
// Using typedef alias name to declare variable
ll a = 20;
printf("%lld", a);
return 0;
}
Output:
20
#include <stdio.h>
#include <string.h>
int main() {
// Using alias to define structure
stu s;
strcpy([Link], "Geeks");
strcpy([Link], "CSE");
s.ID_no = 108;
printf("%s\n", [Link]);
printf("%s\n", [Link]);
printf("%d", s.ID_no);
return 0;
}
Output:
Geeks
CSE
108
CHAPTER 5. STRUCTURE IN C 157
#include <stdio.h>
int main() {
int a = 10;
ip ptr = &a;
printf("%d", *ptr);
return 0;
}
Output:
10
#include <stdio.h>
int main() {
arr a = { 10, 20, 30, 40 };
for (int i = 0; i < 4; i++)
printf("%d ", a[i]);
return 0;
}
Output:
10 20 30 40
typedef vs #define
The #define preprocessor can also be used to create an alias but there are some primary differences between the typedef and #define in C:
• #define is capable of defining aliases for values as well, for instance, you can define 1 as ONE, 3.14 as PI, etc. typedef is limited to giving symbolic
names to types only.
• Preprocessors interpret #define statements, while the compiler interprets typedef statements.
• There should be no semicolon at the end of #define, but a semicolon at the end of typedef.
• In contrast with #define, typedef will actually define a new type by copying and pasting the definition values.
5.10 union
In C, a union is a user-defined data type that can store different data types in the same memory location. Unlike structures, all members of a union
share the same memory, allowing only one member to hold a value at any time.
Example
#include <stdio.h>
#include <string.h>
// Union definition
CHAPTER 5. STRUCTURE IN C 158
union A {
int i;
float f;
char s[20];
};
int main() {
union A a;
// Storing an integer
a.i = 10;
printf("data.i = %d\n", a.i);
// Storing a float
a.f = 220.5;
printf("data.f = %.2f\n", a.f);
// Storing a string
strcpy(a.s, "GfG");
printf("data.s = %s\n", a.s);
return 0;
}
Output
data.i = 10
data.f = 220.50
data.s = GfG
Syntax of Union in C
C Union Declaration
union name {
type1 member1;
type2 member2;
...
};
Ensure the declaration ends with a semicolon. Detailed explanations and examples can be found in the C Programming Course Online with Data
Structures.
// With Declaration
union name {
type member1;
type member2;
...
} var1, var2, ...;
// After Declaration
union name var1, var2, var3, ...;
CHAPTER 5. STRUCTURE IN C 159
var1.member1;
Initialize Union
var1.member1 = val;
Size of Union
#include <stdio.h>
union A {
int x;
char y;
};
union B {
int arr[10];
char y;
};
int main() {
printf("Sizeof A: %ld\n", sizeof(union A));
printf("Sizeof B: %ld\n", sizeof(union B));
return 0;
}
Nested Union
struct Employee {
char name[50];
int id;
union {
float hourlyRate;
float salary;
} payment;
};
File handling in C is the process in which we create, open, read, write, and close operations on a file. C language provides different functions such as
fopen(), fwrite(), fread(), fseek(), fprintf(), etc., to perform input, output, and many different C file operations in our program.
Operations using the C program are done on a prompt/terminal and are not stored anywhere. The output is deleted when the program is closed. In the
software industry, most programs are written to store the information fetched from the program. File handling is necessary for such purposes.
• Reusability: Data stored in the file can be accessed, updated, and deleted anytime, providing high reusability.
• Portability: Files can be transferred without losing any data, minimizing the risk of flawed coding.
• Efficiency: File handling allows accessing a part of a file using fewer instructions, saving time and reducing errors.
• Storage Capacity: Files allow storing a large amount of data without having to worry about storing everything simultaneously in a program.
A file can be classified into two types based on the way the file stores the data:
1. Text Files: Contains data in the form of ASCII characters and generally used to store a stream of characters. They are stored with a .txt file
extension.
2. Binary Files: Contains data in binary form (0’s and 1’s). They are more secure and are generally stored with a .bin file extension.
• Creating a new file – fopen() with attributes like “a", “a+", “w", “w+".
File Pointer in C
A file pointer is a reference to a particular position in the opened file. It is used to perform all file operations such as read, write, close, etc. The FILE
macro is defined inside the <stdio.h> header file.
Syntax
FILE* pointer_name;
The fopen() function is used to open a file with the filename or file path along with the required access modes.
Syntax
fopen(filename, mode);
CHAPTER 5. STRUCTURE IN C 162
Parameters
Return Value
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE* fptr;
fptr = fopen("[Link]", "r");
if (fptr == NULL) {
printf("The file is not opened. The program will now exit.");
exit(0);
}
return 0;
}
In C, the fopen() function is used to open a file in the specified mode. The function returns a file pointer (FILE *) which is used to perform further
operations on the file, such as reading from or writing to it. If the file exists, fopen() opens the particular file; otherwise, in some cases, a new file is
created.
Example Usage
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE* fptr;
return 0;
}
On running the following program, a new file will be created by the name demo_file.txt with the following content:
demo_file.txt
MUSE
#include <stdio.h>
int main() {
// Open file in read mode
FILE *file = fopen("[Link]", "r");
if (file == NULL) {
printf("Error!\n");
return 1;
}
printf("Successfull\n");
Explanation: The file [Link] is opened in read mode ("r"). If the file exists, it opens successfully. If the file doesn’t exist, fopen() returns
NULL, and the program outputs an error message.
#include <stdio.h>
int main() {
// Open file in write mode
FILE *file = fopen("[Link]", "w");
if (file == NULL) {
printf("Error!\n");
return 1;
}
fclose(file);
return 0;
}
Explanation: The file [Link] is opened in write mode ("w"). If the file does not exist, it is created. The program writes a string to the file using
fprintf(). After writing, the file is closed using fclose().
[language=C]
#include <stdio.h>
int main() {
// Open file in append mode
FILE *file = fopen("append_example.txt", "a");
if (file == NULL) {
printf("Error opening file!\n");
return 1;
}
Explanation: The file append_example.txt is opened in append mode ("a"). If the file exists, the new content is appended to the end of the file. If
the file does not exist, it is created.
#include <stdio.h>
int main() {
// Try to open a non-existing file
FILE *file = fopen("non_existent_file.txt", "r");
if (file == NULL) {
perror("Error");
return 1;
}
Explanation: The program attempts to open a file that does not exist, and perror() displays the system error message.
The fopen() function can also create a file if it does not exist. Use modes like w, w+, wb, etc.
CHAPTER 5. STRUCTURE IN C 165
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE* fptr;
fptr = fopen("[Link]", "w");
if (fptr == NULL) {
printf("The file is not opened. The program will exit now.");
exit(0);
} else {
printf("The file is created Successfully.");
}
return 0;
}
The file read operation can be performed using functions like fscanf(), fgets(), fgetc(), etc.
FILE *fptr;
fptr = fopen("[Link]", "r");
fscanf(fptr, "%s %s %s %d", str1, str2, str3, &year);
char c = fgetc(fptr);
Write to a File
File write operations can be performed by functions like fprintf(), fputs(), fputc(), etc.
FILE *fptr;
fptr = fopen("[Link]", "w");
fprintf(fptr, "%s %s %s %d", "We", "are", "writing", 2025);
The file read operation in C can be performed using functions fscanf() or fgets(). Both functions perform similar operations to scanf and gets(),
but with an additional parameter: the file pointer. Other functions can also be used to read from a file:
Function Description
fscanf() Use formatted string and variable arguments list to take input from a file.
fgets() Input the whole line from the file.
fgetc() Reads a single character from the file.
fgetw() Reads a number from a file.
fread() Reads the specified bytes of data from a binary file.
Example:
FILE *fptr;
fptr = fopen("[Link]", "r");
fscanf(fptr, "%s %s %s %d", str1, str2, str3, &year);
char c = fgetc(fptr);
CHAPTER 5. STRUCTURE IN C 166
getc() and other file reading functions return EOF (End Of File) when they reach the end of the file. EOF indicates the end of the file, and its value is
implementation-defined.
File write operations can be performed using the functions fprintf() and fputs() with similarities to read operations. Other functions that can be
used to write data to a file include:
Function Description
fprintf() Similar to printf(), it uses a formatted string and variable arguments list to print output to the file.
fputs() Prints the whole line in the file, adding a newline at the end.
fputc() Prints a single character into the file.
fputw() Prints a number to the file.
fwrite() Writes the specified number of bytes to a binary file.
Example:
FILE *fptr;
fptr = fopen("[Link]", "w");
fprintf(fptr, "%s %s %s %d", "We", "are", "in", 2012);
fputc(’a’, fptr);
The fclose() function is used to close a file. Always close a file after performing file operations to free up resources.
FILE *fptr;
fptr = fopen("[Link]", "w");
// Some file operations
fclose(fptr);
5.17.1 fseek()
The fseek() function moves the file pointer to a specified location. Its syntax is:
Example of fseek():
#include <stdio.h>
int main() {
FILE* fp;
fp = fopen("[Link]", "r");
fseek(fp, 0, SEEK_END);
printf("%ld", ftell(fp));
fclose(fp);
return 0;
}
In this article, we will discuss the EOF, getc() function, and feof() function in C.
CHAPTER 5. STRUCTURE IN C 167
What is EOF?
In C, EOF is a constant macro defined in the <stdlib.h> header file that is used to denote the end of the file in C file handling. It is used by various file
reading functions such as fread(), gets(), getc(), etc.
getc() Function
The getc() function is used to read a single character from the given file stream. It is implemented as a macro in <stdio.h> header file.
Syntax
getc(fptr);
Parameters
Return Value
It returns the character read from the file stream. If some error occurs or the End-Of-File is reached, it returns EOF.
feof() Function
The feof() function is used to check whether the file pointer to a stream is pointing to the end of the file or not. It returns a non-zero value if the end
is reached, otherwise, it returns 0.
5.18.1 Syntax
feof(fptr);
5.18.2 Parameters
Return Value
Returns a non-zero value (usually 1) if the end of the file is reached. Otherwise, it returns 0.
getc() returns the End of File (EOF) when the end of the file is reached. getc() also returns EOF when it fails. So, only comparing the value returned
by getc() with EOF is not sufficient to check for the actual end of the file. To solve this problem, C provides feof().
Example
#include <stdio.h>
int main() {
FILE *fptr = fopen("[Link]", "w");
char ch;
if (ch == EOF)
printf("End of File or Unable to Read");
else
printf("Read Character: %c", ch);
fclose(fptr);
return 0;
}
In the above program, the getc() function should be unable to read as the file is opened in the write mode only. But it still returns EOF, which makes
it difficult to find the source of error. Here, the feof() function can be specifically used to check for End of File.
fgets()
The fgets() function reads a line from the specified stream and stores it into the string pointed to by str. It stops when either (n-1) characters are
read, the newline character is read, or the end-of-file is reached, whichever comes first.
Syntax
Parameters
• n: Maximum number of characters to be copied into str (including the terminating null character).
Return Value
The fgets() function returns a pointer to the string where the input is stored.
Example of fgets()
#include <stdio.h>
#define MAX 15
int main()
{
// defining buffer
char buf[MAX];
return 0;
}
gets()
The gets() function reads characters from the standard input (stdin) and stores them as a C string into str until a newline character or the end-of-file
is reached.
It is not safe to use because it does not check the array bound. It is used to read strings from the user until a newline character is encountered.
Syntax
Example of gets()
#include <stdio.h>
#define MAX 15
int main()
{
// defining buffer
char buf[MAX];
return 0;
}
This document covers the usage of some standard C functions related to file handling and formatted input/output operations, including fprintf(),
scanf(), fscanf(), and fread().
fprintf() is used to print content to a file instead of the standard output console.
Syntax:
int fprintf(FILE *fptr, const char *str, ...);
Example:
#include<stdio.h>
int main()
{
int i, n=2;
char str[50];
{
puts("Enter a name");
scanf("%[^\n]%*c", str);
fprintf(fptr, "%d.%s\n", i, str);
}
fclose(fptr);
return 0;
}
Input:
• MUSE
• AIML
Output:
scanf() is used to read formatted input from stdin. The fscanf() function is used to read formatted input from a file stream.
Syntax:
int scanf(const char *characters_set);
Example:
#include <stdio.h>
int main()
{
int a;
scanf("%d", &a);
printf("a = %d", a);
return 0;
}
Input:
Output:
a = 2
Syntax:
int fscanf(FILE *ptr, const char *format, ...);
#include <stdio.h>
int main()
{
FILE* ptr = fopen("[Link]", "r");
if (ptr == NULL)
{
printf("no such file.");
return 0;
}
char buf[100];
while (fscanf(ptr, "%*s %*s %s ", buf) == 1)
printf("%s\n", buf);
return 0;
}
Output:
hyderabad
delhi
bangalore
The fread() function in C is used to read data from a file stream into a buffer.
Syntax:
size_t fread(void *buffer, size_t size, size_t count, FILE *stream);
Example:
#include <stdio.h>
int main()
{
FILE *file;
int buffer[5];
Output:
Element 1: 10
Element 2: 20
Element 3: 30
Element 4: 40
Element 5: 50
fseek() and rewind() are functions used for file positioning in C, defined in the <stdio.h> header file. This document discusses the differences in the
usage and behavior of both functions. fseek() sets the file position indicator to a specified offset from the specified origin.
Syntax:
Parameters:
Return Value:
rewind() moves the file pointer to the beginning of the file stream.
Syntax:
Parameters:
Return Value:
The following table summarizes the differences between fseek() and rewind():
fseek rewind
Used to move the file pointer to a specific position. Used to move the file pointer to the beginning of the file stream.
Syntax: int fseek(FILE *stream, long offset, int origin); Syntax: void rewind(FILE *stream);
Returns 0 if successful, and a non-zero value if an error occurs. Does not return any value.
The stream error indicator is not cleared. The stream error indicator is cleared.
Example: fseek(file, 10, SEEK_SET); Example: rewind(file);
Moves the file pointer 10 bytes from the beginning of the file. Moves the file pointer to the beginning of the file.
Note from the C99 Standard: The rewind function sets the file position indicator for the stream pointed to by the stream at the beginning of the
file. It is equivalent to:
except that the error indicator for the stream is also cleared.
The following code example sets the file position indicator of an input stream back to the beginning using rewind(). However, there is no way to check
whether the rewind() was successful.
Example:
int main()
{
FILE* fp = fopen("[Link]", "r");
if (fp == NULL) {
/* Handle open error */
}
return 0;
}
In the above code, fseek() can be used instead of rewind() to check if the operation succeeded.
The most important function in C is the main() function. It is mostly defined with a return type of int and without parameters:
int main() {
// ...
}
CHAPTER 5. STRUCTURE IN C 174
We can also give command-line arguments in C. Command-line arguments are the values given after the name of the program in the command-line shell
of Operating Systems. These arguments are handled by the main() function of a C program.
To pass command-line arguments, we typically define main() with two arguments: the first argument is the number of command-line arguments, and
the second is a list of command-line arguments.
Syntax
Here,
• argc (Argument Count) is an integer variable that stores the number of command-line arguments passed by the user, including the name of the
program. For example, if we pass one argument to a program, the value of argc would be 2 (one for the argument and one for the program
name). The value of argc should be non-negative.
• argv (Argument Vector) is an array of character pointers listing all the arguments. If argc is greater than zero, the array elements from argv[0]
to argv[argc-1] will contain pointers to strings. argv[0] is the name of the program. After that, each element up to argv[argc-1] is a
command-line argument.
Note: For better understanding, run this code on your Linux machine.
Example
#include <stdio.h>
return 0;
}
Output
./main
geeks
for
geeks
• They are used to control programs from outside instead of hardcoding those values inside the code.
• argv[1] points to the first command-line argument, and argv[argc-1] points to the last argument.
Note: You pass all command-line arguments separated by a space. If an argument itself has a space, you can pass such arguments by putting them
inside double quotes "" or single quotes ”.
Example
#include <stdio.h>
if (argc == 1) {
printf("\nNo Extra Command Line Argument Passed Other Than Program Name");
}
if (argc >= 2) {
printf("\nNumber Of Arguments Passed: %d", argc);
printf("\n----Following Are The Command Line Arguments Passed----");
for (int i = 0; i < argc; i++)
printf("\nargv[%d]: %s", i, argv[i]);
}
return 0;
}
1. Without argument:
When the above code is compiled and executed without passing any argument, it produces the following output:
$ ./[Link]
Program Name Is: ./[Link]
No Extra Command Line Argument Passed Other Than Program Name
2. Three arguments:
When the above code is compiled and executed with three arguments, it produces the following output:
3. Single Argument:
When the above code is compiled and executed with a single argument separated by space but inside double quotes, it produces the following output:
CHAPTER 5. STRUCTURE IN C 176
When the above code is compiled and executed with a single argument separated by space but inside single quotes, it produces the following output: