Could someone help me understand and run this code in its entirety? I think all
ID: 3697685 • Letter: C
Question
Could someone help me understand and run this code in its entirety? I think all you have to do is create txt files, which I have, but for some reason it will only read the contacts.txt file i created and it will write on the copy.txt file, but i would really like to know how to run the rest of the program. Please help!!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <conio.h>
#include <math.h>
#include <stdbool.h>
#define bool int
#define true 1
#define false 0
struct contactStruct {
int ID;
char fName[20];
char lName[20];
char pNumber[15];
char email[50];
char address[100];
};
typedef struct contactStruct contactStrt;
// Read a struct assuming fields are separated by space
void readStruct(contactStrt * cStruct, FILE* fHandle)
{
fscanf(fHandle, "%d", (*cStruct).ID);
fscanf(fHandle, "%s", (*cStruct).fName);
fscanf(fHandle, "%s", (*cStruct).lName);
fscanf(fHandle, "%s", (*cStruct).pNumber);
fscanf(fHandle, "%s", (*cStruct).email);
fscanf(fHandle, "%s", (*cStruct).address);
}
// write a struct to the file assuming fields are separated by space
void writeStruct(contactStrt* cStruct, FILE* fHandle)
{
fprintf(fHandle, "%d,", (*cStruct).ID);
fprintf(fHandle, "%s,", (*cStruct).fName);
fprintf(fHandle, "%s,", (*cStruct).lName);
fprintf(fHandle, "%s,", (*cStruct).pNumber);
fprintf(fHandle, "%s,", (*cStruct).email);
fprintf(fHandle, "%s", (*cStruct).address);
fprintf(fHandle, "%s", " ");
}
// reads one line splits on commas and puts into a struct
bool readLine(contactStrt * cStruct, FILE* fHandle)
{
char line[255];
char delim[2] = ",";
char *token;
if (fgets(line, 254, fHandle) != NULL) // read one line up to 254 charactes and put it in line!
{
// Tokenize it
token = strtok(line, delim);
(*cStruct).ID = atoi(token);
//strcpy((*cStruct).ID, token);
token = strtok(NULL, delim);
strcpy((*cStruct).fName, token);
token = strtok(NULL, delim);
strcpy((*cStruct).lName, token);
token = strtok(NULL, delim);
strcpy((*cStruct).pNumber, token);
token = strtok(NULL, delim);
strcpy((*cStruct).email, token);
token = strtok(NULL, delim);
strcpy((*cStruct).address, token);
(*cStruct).address[strlen((*cStruct).address) - 1] = '';
return true;
}
else
{
return false;
}
}
// Writes one line in the file
void writeLine(contactStrt * cStruct, FILE* fHandle)
{
char line[255] = "";
char id[50];
&itoa((*cStruct).ID, id, 10=0);
strcat(line, id);
strcat(line, ",");
strcat(line, (*cStruct).fName);
strcat(line, ",");
strcat(line, (*cStruct).lName);
strcat(line, ",");
strcat(line, (*cStruct).pNumber);
strcat(line, ",");
strcat(line, (*cStruct).email);
strcat(line, ",");
strcat(line, (*cStruct).address);
strcat(line, " ");
fprintf(fHandle, "%s", line);
}
// reads the whole file and populates list of contacts in contactsList
// it also keeps track of number of contacts read from the file in
// numOfContacts
void readFile(contactStrt contactsList[50], int* numOfContacts, FILE* fHandle)
{
*numOfContacts = 0;
while (readLine(&contactsList[*numOfContacts], fHandle) == true)
{
*numOfContacts = *numOfContacts + 1;
}
}
void writeFile(contactStrt contactsList[50], int numOfContacts, FILE* fHandle)
{
int i;
for (i = 0; i < numOfContacts; i = i + 1)
{
writeLine(&contactsList[i], fHandle);
}
}
// Search contacts using first name
void searchFirstName(contactStrt contactsList[50], int numOfContacts,
char fName[50], contactStrt resultList[50], int * numOfResult)
{
int ind;
*numOfResult = 0;
for (ind = 0; ind < numOfContacts; ind = ind + 1)
{
if (strcmp(fName, contactsList[ind].fName) == 0)
{
resultList[*numOfResult].ID = contactsList[ind].ID;
strcpy(resultList[*numOfResult].fName, contactsList[ind].fName);
strcpy(resultList[*numOfResult].lName, contactsList[ind].lName);
strcpy(resultList[*numOfResult].pNumber, contactsList[ind].pNumber);
strcpy(resultList[*numOfResult].address, contactsList[ind].address);
strcpy(resultList[*numOfResult].email, contactsList[ind].email);
*numOfResult = *numOfResult + 1;
}
}
}
// Search contacts using first name
void searchPhoneNumber(contactStrt contactsList[50], int numOfContacts,
char pNumber[50], contactStrt resultList[50], int * numOfResult)
{
int ind;
*numOfResult = 0;
for (ind = 0; ind < numOfContacts; ind = ind + 1)
{
if (strcmp(pNumber, contactsList[ind].pNumber) == 0)
{
resultList[*numOfResult].ID = contactsList[ind].ID;
strcpy(resultList[*numOfResult].fName, contactsList[ind].fName);
strcpy(resultList[*numOfResult].lName, contactsList[ind].lName);
strcpy(resultList[*numOfResult].pNumber, contactsList[ind].pNumber);
strcpy(resultList[*numOfResult].address, contactsList[ind].address);
strcpy(resultList[*numOfResult].email, contactsList[ind].email);
*numOfResult = *numOfResult + 1;
}
}
}
void swapContacts(contactStrt* first, contactStrt* second)
{
contactStrt temp;
temp.ID = (*first).ID;
strcpy(temp.fName, (*first).fName);
strcpy(temp.lName, (*first).lName);
strcpy(temp.pNumber, (*first).pNumber);
strcpy(temp.address, (*first).address);
strcpy(temp.email, (*first).email);
(*first).ID = (*second).ID;
strcpy((*first).fName, (*second).fName);
strcpy((*first).lName, (*second).lName);
strcpy((*first).pNumber, (*second).pNumber);
strcpy((*first).address, (*second).address);
strcpy((*first).email, (*second).email);
(*second).ID = temp.ID;
strcpy((*second).fName, temp.fName);
strcpy((*second).lName, temp.lName);
strcpy((*second).pNumber, temp.pNumber);
strcpy((*second).address, temp.address);
strcpy((*second).email, temp.email);
}
void sortByID(contactStrt contactsList[50], int numOfContacts)
{
int i, j;
contactStrt temp;
for (i = 0; i<numOfContacts; i = i + 1)
{
for (j = i + 1; j<numOfContacts; j = j + 1)
{
if (contactsList[i].ID>contactsList[j].ID)
{
swapContacts(&contactsList[i], &contactsList[j]);
}
}
}
}
void sortByfNames(contactStrt contactsList[50], int numOfContacts)
{
int i, j;
contactStrt temp;
for (i = 0; i<numOfContacts; i = i + 1)
{
for (j = i + 1; j<numOfContacts; j = j + 1)
{
if (strcmp(contactsList[i].fName, contactsList[j].fName)>0)
{
swapContacts(&contactsList[i], &contactsList[j]);
}
}
}
}
//
void findIDGreater(contactStrt contactsList[50], int numOfContacts, int base
, contactStrt resultList[50], int * numOfResult)
{
int ind;
*numOfResult = 0;
for (ind = 0; ind < numOfContacts; ind = ind + 1)
{
if (contactsList[ind].ID > base)
{
resultList[*numOfResult].ID = contactsList[ind].ID;
strcpy(resultList[*numOfResult].fName, contactsList[ind].fName);
strcpy(resultList[*numOfResult].lName, contactsList[ind].lName);
strcpy(resultList[*numOfResult].pNumber, contactsList[ind].pNumber);
strcpy(resultList[*numOfResult].address, contactsList[ind].address);
strcpy(resultList[*numOfResult].email, contactsList[ind].email);
*numOfResult = *numOfResult + 1;
}
}
}
void printSearchResult(contactStrt resultList[50], int * numOfResult)
{
int ind;
for (ind = 0; ind < numOfResult; ind = ind + 1)
{
printf(" %d %s %s %s %s %s ", resultList[ind].ID, resultList[ind].fName
, resultList[ind].lName, resultList[ind].pNumber, resultList[ind].email
, resultList[ind].address);
}
}
// Delete a contact
bool deleteContactByPnumber(contactStrt contactsList[50], int *numOfContacts, char pNumber[15])
{
int ind;
for (ind = 0; ind < *numOfContacts; ind = ind + 1)
{
if (strcmp(pNumber, contactsList[ind].pNumber) == 0)
{
break;
}
}
if (ind < *numOfContacts)
{
for (; ind < *numOfContacts; ind = ind + 1)
{
contactsList[ind].ID = contactsList[ind + 1].ID;
strcpy(contactsList[ind].fName, contactsList[ind + 1].fName);
strcpy(contactsList[ind].lName, contactsList[ind + 1].lName);
strcpy(contactsList[ind].pNumber, contactsList[ind + 1].pNumber);
strcpy(contactsList[ind].address, contactsList[ind + 1].address);
strcpy(contactsList[ind].email, contactsList[ind + 1].email);
}
*numOfContacts = *numOfContacts - 1;
return true;
}
else
{
printf("Couldn't find that phone number! ");
return false;
}
}
int main()
{
// Variables
char inFileName[255] = "contacts.txt"; // file names in windows can't be longer than 255 characters!
char outFileName[255] = "copy.txt";
FILE* fHandle = NULL; // File handler
contactStrt cStruct;
contactStrt contactsList[50];
int numOfContacts;
int ind;
printf("Openning the file in read mod... ");
fHandle = fopen(inFileName, "r");
if (fHandle == NULL)
{
printf("ERR! Unable to open input file. ");
return false;
}
printf("Reading from the file... ");
//readStruct(&cStruct, fHandle);
//readLine(&cStruct, fHandle);
readFile(contactsList, &numOfContacts, fHandle);
printf("Closing and openning the file in write mod... ");
fclose(fHandle);
// Search for firstname
contactStrt resultList[50];
int numOfResult;
char fName[50];
char pNumber[15];
printf("Please enter a first name: ");
scanf("%s", fName);
searchFirstName(contactsList, numOfContacts, fName, resultList, &numOfResult);
printSearchResult(resultList, numOfResult);
// sort by ID
sortByID(contactsList, numOfContacts);
printf(" Sort By ID: =========================== ");
printSearchResult(contactsList, numOfContacts);
// Sort by fName
sortByfNames(contactsList, numOfContacts);
printf(" Sort By First Names: =========================== ");
printSearchResult(contactsList, numOfContacts);
fHandle = fopen(outFileName, "w");
if (fHandle == NULL)
{
printf("ERR! Unable to open input file. ");
return false;
}
// Delete a contact
printf("Please enter a phone number: ");
scanf("%s", pNumber);
for (ind = 0; ind < numOfContacts; ind = ind + 1)
{
bool res = deleteContactByPnumber(contactsList, &numOfContacts, pNumber);
if (res == false)
{
break;
}
}
//writeStruct(&cStruct, fHandle);
//writeLine(&cStruct, fHandle);
writeFile(contactsList, numOfContacts, fHandle);
printf("Closing the file. ");
fclose(fHandle);
return 0;
}
Explanation / Answer
Working with files :
When accessing files through C program , the first necessity is to have a way to access the files. For C File I/O you need to use a FILE pointer, which will let the program keep track of the file being accessed. The pointer is called as file pointer . Lets see the example
To open a file you need to use the fopen() function, which returns a FILE pointer. Once you've opened a file, you can use the FILE pointer to let the compiler perform input and output functions on the file.
Here filename is string literal which you will use to name your file and mode can have one of the following values
Note that it's possible for fopen to fail even if your program is perfectly correct: you might try to open a file specified by the user, and that file might not exist (or it might be write-protected). In those cases, fopen will create a file if you specify file mode as "w", "w+", "a", or "a+" otherwise it will return 0, the NULL pointer.
Here's a simple example of using fopen:
This code will open abc.txt for reading in text mode. To open a file in a binary mode you must add a b to the end of the mode string; for example, "rb" (for the reading and writing modes, you can add the b either after the plus sign - "r+b" - or before - "rb+")
To close a function you can use the function:
fclose returns zero if the file is closed successfully.
An example of fclose is:
To work with text input and output, you use fprintf and fscanf, both of which are similar to their friends printf and scanf except that you must pass the FILE pointer as first argument.
Try out following example:
Thsi will create a file test.txt in /tmp directory and will write This is testing in that file.
Here is an example which will be used to read lines from a file:
It is also possible to read (or write) a single character at a time--this can be useful if you wish to perform character-by-character input. The fgetc () function, which takes a file pointer, and returns an int, will let you read a single character from a file:
The fgetc() returns an int. What this actually means is that when it reads a normal character in the file, it will return a value suitable for storing in an unsigned char (basically, a number in the range 0 to 255). On the other hand, when you're at the very end of the file, you can't get a character value--in this case, fgetc will return "EOF" end of file , which is a constnat that indicates that you've reached the end of the file.
The fputc function allows you to write a character at a time--you might find this useful if you wanted to copy a file character by character. It looks like this:
Note that the first argument should be in the range of an unsigned char so that it is a valid character. The second argument is the file to write to. On success, fputc will return the value c, and on failure, it will return EOF.
FILE *fp;