Skip to main content

Excercises

Concept Questions

  1. Explain the purpose of a file pointer and describe how fopen() is used to create one. What does it mean when fopen() returns NULL?

  2. Describe the three file access modes ("r", "w", and "a") and explain when you would use each one. What happens to existing file content in each mode?

  3. Explain why it is critical to check the return value of fopen() before using a file pointer. What problems could occur if you skip this check?

  4. Compare and contrast fgets() and fscanf() for reading data from files. When would you use each function?

  5. Explain what a regular expression is in the context of fscanf(). Provide an example of how %[^\n] works and why it is useful for reading lines from a file.

  6. A data file contains student records in the following format:

    <student_id>:<name>:<gpa>

    Example:

    101:Alice:3.85
    102:Bob:3.92
    103:Charlie Brown:3.65

    a) Declare a struct named Student to store this information. You may assume the student's name will have no more than 50 characters.

    b) Write a function named readStudents that accepts a filename, an array of Student structs, and the maximum capacity. The function should read all student records from the file and return the number of students read.

    c) Write a function named writeStudents that accepts a filename and an array of Student structs with a count. The function should write all students to the file in the same format.

Walkthrough

a) Using tables to track variables and file operations, trace through the execution of this program. b) What is the exact output of the following program?

#include <stdio.h>

struct Score
{
int id;
float value;
};

int main(void)
{
FILE *fp;
struct Score scores[3] = {
{1, 85.53},
{2, 92.01},
{3, 78.62}
};
int i;
int rc = 0;

// Write to file
fp = fopen("scores.txt", "w");
if (fp != NULL) {
for (i = 2; i >=0; i--) {
fprintf(fp, "%d %.1f\n", scores[i].id,
scores[i].value);
}
fclose(fp);
}

// Read from file
fp = fopen("scores.txt", "r");
if (fp != NULL) {
while (fscanf(fp, "%d %f", &scores[i].id,
&scores[i].value) == 2) {
printf("ID: %d, Value: %.2f\n",
scores[i].id, scores[i].value);
i++;
}
fclose(fp);
}

return rc;
}

Debugging

The following program is intended to read a file containing employee records and display them one per line. Each line of the file contains an employee ID, name, and salary in the following format:

<id>;<name>:<salary>

You may assume the name is no more than 50 characters long.

The program has several errors. Identify and fix them.

#include <stdio.h>

struct Employee
{
int id;
char name[50];
float salary;
};

int main(void)
{
FILE *fp = fopen("employees.txt", "w");
struct Employee emp;
int rc = 0;

while (fscanf(fp, "%d %s %f", &emp.id, emp.name,
&emp.salary) == 3) {
printf("ID: %d, Name: %s, Salary: $%.2f\n",
emp.id, emp.name, emp.salary);
}

fclose(fp);
return rc;
}
  1. Identify all errors in the above code (syntax, logical, and stylistic)

  2. Rewrite the program to fix all errors

Programming

a) Create a struct named Contact that stores:

  • Name (string, max 100 characters)
  • Email (string, max 100 characters)
  • Phone (string, max 20 characters)

b) Write a function named addContact that accepts a filename, a pointer to a Contact struct, and appends it to the file in the following format:

<name>|<email>|<phone>

c) Write a function named displayContacts that accepts a filename and reads all contacts from the file, displaying them in a formatted table. The Name and email columns are 20 characters wide, and the phone column is 16 characters wide. No matter how long the actual name and emails are, we print only the first 20 characters:

Name                 | Email                | Phone
--------------------|----------------------|------------------

d) Write a function named findContact that accepts a filename and a name to search for. The function should read through the file and display the contact information if found, or print a message if not found.