Read and Modify CSV File
Files and Pointers
A CSV file, Comma Separated Vector, is a file format normally used to implement log files or
simple database applications. It is a text file that uses the .csv file extension. Every row of the file
is a series of fields separated by commas and terminating with a carrage return. For example,
we have a phone book of friends: Bob is 19 his number is 514-123-4567, and Mary is 20 her
number is 450-345-7890. This would be stored in the CSV file as:
Bob, 19, 514-123-4567
Mary, 20, 450-345-7890
The comma and the carrage return are reserved words and cannot be used in the file to mean
anything else. In CSV2, escape characters are used to overcome this limitation, but for this
assignment we are not implmenting CSV2. It is optional to include a space after the comma.
A CSV record is one row of information. For example: Bob, 19, 514-123-4567 is a record. In this
case, it is populated by three fields, deliniated by the comma and carrage return: field #1 is Bob,
field #2 is 19, and field #3 is 514-123-4567. It is standard to refer to the contents of a CSV file
as records and fields.
Create a program that does the following:
1) Ask for a name
2) Ask for a replacement name
3) Search for the record in the CSV file that belongs to name 1
4) Load that record into an array of size 1000 characters
5) Using pointers and no library functions and no array indexes, properly replace the name
in the record with the replacement name
6) Then write this updated record back into the CSV file replacing the old record
7) Program terminates
In the above, steps 1 – 2 are in the main function.
Steps 3 – 4 are in a function called void FindRecord(char *filename, char *name, char record[]),
it is invoked from the main function. FindRecord opens the file and reads each record looking for
the matching record name. It then returns the matching record in the array record[] and closes
the file.
Step 5 is in a function called void Replace(char *name, char *newname, char record[]), it is
invoked from the main function. It replaces the name in the array record[] with newname. The
updated information is returned through the array record[]. You must use pointers.
Step 6 is in a function called void SaveRecord(char *filename, char *name, char record[]) and it
is invoked from the main function. SaveRecord replaces the record in CSV that matches name
with the array record[]. It then closes the file. The entire CSV file must be preserved as in its
original form except the one record that is replaced.
Do not use global variables.
Using vim, create a csv file called phonebook.csv and populate it with 5 records. Each record
will be formatted as: name, age, phone_number.
Your C program is called Replace.c.
Solution
#include <stdio.h>
#include <string.h>
// max allowed buffer size
#define MAX_BUFFER_SIZE 1000
voidFindRecord(char *filename, char *name, char record[])
{
FILE* file;
char buffer[MAX_BUFFER_SIZE];
file = fopen(filename, “r”); // open file in reading mode
while (fgets(buffer, MAX_BUFFER_SIZE, (FILE*)file)) // read each recor4d line by line
{
if (strstr(buffer, name)) // if we found goal name in current record
{
strcpy(record, buffer); // make copy of this record into output buffer
}
}
fclose(file);
}
void Replace(char *name, char *newname, char record[])
{
char buffer[MAX_BUFFER_SIZE];
char *p;
if (!(p = strstr(record, name))) // if we did’t find name in record
return; // nothing to do
strcpy(buffer, record); // make copy of source record
// copy new name from found position and then remain part of string
//sprintf(p, “%s%s”, newname, buffer + strlen(name));
strcpy(p, newname);
strcpy(p + strlen(newname), buffer + strlen(name));
}
voidSaveRecord(char *filename, char *name, char record[])
{
// for replace record in file use 2 files
charshadowfilename[MAX_BUFFER_SIZE]; // shadow file is necessary to make temporary output
shadowfilename[0] = ‘$’;
strcpy(shadowfilename + 1, filename);
FILE* fileIn = fopen(filename, “r”); // open source file for reading
FILE* fileOut = fopen(shadowfilename, “w”); // open shadow file for writing
char buffer[MAX_BUFFER_SIZE];
while (fgets(buffer, MAX_BUFFER_SIZE, fileIn))
{
if (strstr(buffer, name))
{
fprintf(fileOut, “%s”, record); // use updated record for record whick match ‘name’
}
else
{
fprintf(fileOut, “%s”, buffer); // duplicate lines from source file which doesn’t match ‘name’
}
}
fclose(fileOut); // close output file
fclose(fileIn); // close input file
remove(filename);
rename(shadowfilename, filename);
}
int main()
{
char name[MAX_BUFFER_SIZE]; // buffer for name
charnewname[MAX_BUFFER_SIZE]; // buffer for new name
char filename[] = “phonebook.csv”;// csv file name
// 1. Ask for a name
printf(“Enter name:”);
scanf(“%s”, name); // enter name
// 2. Ask for a replacement name
printf(“Enter new name:”);
scanf(“%s”, newname); // enter ne name
char record[MAX_BUFFER_SIZE]; // buffer for target record
// 3. search for the record in the CSV file
FindRecord(filename, name, record);
// 5. replace the name in the record with the replacement name
Replace(name, newname, record);
// 6. write updated record back into the file
SaveRecord(filename, name, record);
// 7. Program terminates
return 0;
}