Searching a name in a text file by ID - c

I have a text file with 2 lines in it:
Voicu;Catalin;1234;2.32
Diana;Cadar;2345;1.01
I'm trying to make my program search in .txt file the ID (1234 or 2345) and match it to the name. Below is the code I've tried to make, but it won't find the ID in .txt after I write it in first scanf, the first thing that appears is the "else" line.
void alegereStudent(struct student *stud)
{
FILE *scStudenti = fopen("studenti.txt", "a");
char *error;
int i=0,n;
if(scStudenti==NULL)
{
error = strerror(errno);
printf("Fisierul nu poate fi creat: \n %s", error);
}
printf("\nIntroduceti Numele: ");
scanf("%39s", stud->numeStudent);
printf("Introduceti Prenumele: ");
scanf("%39s", stud->prenumeStudent);
printf("Introduceti ID-ul studentului: ");
scanf("%d", &stud->idStudent);
printf("Introduceti Media de admitere: ");
scanf("%f", &stud->medieAdmitere);
fprintf(scStudenti,"<%s>;", stud->numeStudent);
fprintf(scStudenti,"<%s>;", stud->prenumeStudent);
fprintf(scStudenti,"<%d>;", stud->idStudent);
fprintf(scStudenti,"<%.2f>\n", stud->medieAdmitere);
fclose(scStudenti);
}
//
void optiunea_2()
{
printf("\n1.Despre studenti.\n");
printf("2.Despre profesori.\n");
printf("3.Revenire la meniu principal.\n");
printf("\nAlegeti o optiune: ");
scanf("%d",&alegere_opt2);
switch(alegere_opt2)
{
case 1: while(&stud!=NULL)
{
FILE *scStudenti = fopen("studenti.txt", "r");
char *error;
int cautareID;
if(scStudenti==NULL)
{
error = strerror(errno);
printf("Fisierul nu poate fi creat: \n %s", error);
}
printf("\nIntroduceti ID-ul studentului: ");
scanf("%d", &cautareID);
fscanf(scStudenti,"%d",&stud->idStudent);
if(cautareID==&stud->idStudent)
{
printf("Numele Studentului este %s %s",&stud->numeStudent, &stud->prenumeStudent);
}
else
printf("\nAcest ID nu exista!\n");
optiunea_2();
}break;

fprintf(scStudenti,"<%s>;", stud->numeStudent);
fprintf(scStudenti,"<%s>;", stud->prenumeStudent);
fprintf(scStudenti,"<%d>;", stud->idStudent);
fprintf(scStudenti,"<%.2f>\n", stud->medieAdmitere);
fclose(scStudenti);
This makes formatting much more difficult. The output file will contain:
<first>;<last>;<1234>;<0.5>
You want to start with a new file and simplify the output to write:
first;last;1234;0.5
Don't always put & in front of integer. Just use:
if(cautareID == stud->idStudent)
{
...
}
Example:
const char *filename = "studenti.txt";
void alegereStudent()
{
struct student stud;
FILE *scStudenti = fopen(filename, "a");
if(scStudenti == NULL)
{
printf("error\n");
return;
}
printf("\nIntroduceti Numele: ");
scanf("%39s", stud.numeStudent);
printf("Introduceti Prenumele: ");
scanf("%39s", stud.prenumeStudent);
printf("Introduceti ID-ul studentului: ");
scanf("%d", &stud.idStudent);
printf("Introduceti Media de admitere: ");
scanf("%f", &stud.medieAdmitere);
fprintf(scStudenti, "%s;", stud.numeStudent);
fprintf(scStudenti, "%s;", stud.prenumeStudent);
fprintf(scStudenti, "%d;", stud.idStudent);
fprintf(scStudenti, "%.2f\n", stud.medieAdmitere);
fclose(scStudenti);
}
void find_by_id(int id)
{
FILE *fin = fopen(filename, "r");
if(!fin)
return;
int count = 0;
struct student stud;
while(fscanf(fin, "%39[^;];%39[^;];%d;%f\n",
stud.numeStudent, stud.prenumeStudent, &stud.idStudent, &stud.medieAdmitere) == 4)
{
if(id == stud.idStudent)
{
printf("found %s %s\n", stud.numeStudent, stud.prenumeStudent);
}
count++;
}
if(count == 0)
printf("failed to read any record. Start with a new file.\n");
}
int main(void)
{
alegereStudent();
find_by_id(1234);
return 0;
}
If <> characters are added, then read according to that format, you then have to remove the extra <> characters from the string.
void alegereStudent()
{
struct student stud;
...
fprintf(scStudenti, "<%s>;", stud.numeStudent);
fprintf(scStudenti, "<%s>;", stud.prenumeStudent);
fprintf(scStudenti, "<%d>;", stud.idStudent);
fprintf(scStudenti, "<%.2f>\n", stud.medieAdmitere);
fclose(scStudenti);
}
void find_by_id(int id)
{
...
struct student stud;
while(fscanf(fin, "%39[^;];%39[^;];<%d>;<%f>\n",
stud.numeStudent, stud.prenumeStudent, &stud.idStudent, &stud.medieAdmitere) == 4)
{
if(id == stud.idStudent)
{
char *p;
size_t i;
//remove the extra <> characters
p = stud.numeStudent;
if (strlen(p) > 1)
{
for(i = 1; i < strlen(p) - 1; i++)
p[i - 1] = p[i];
p[i - 1] = 0;
}
//remove the extra <> characters
p = stud.prenumeStudent;
if (strlen(p) > 1)
{
for(i = 1; i < strlen(p) - 1; i++)
p[i - 1] = p[i];
p[i - 1] = 0;
}
printf("found %s %s\n", stud.numeStudent, stud.prenumeStudent);
}
count++;
}
if(count == 0)
printf("failed to read any record. Start with a new file.\n");
}

#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char const *filename = "test.txt";
FILE *input = fopen(filename, "r");
if (!input) {
fprintf(stderr, "Couldn't open \"%s\" for reading!\n\n", filename);
return EXIT_FAILURE;
}
char name[101];
char surname[101];
int id;
double value;
while (fscanf(input, "%100[^;];%100[^;];%d;%lf%*[\n]", name, surname, &id, &value) == 4) {
if (id == 2345) {
printf("Found \"%s %s\" by id %d\n\n", name, surname, id);
break;
}
}
}

Related

Get first letter from C string

I have a program in C which is basically a contact book, and I've already done all the functionalities (add contact, delete etc) but I also have to implement a way to search for contacts by the initial letter (the user type any letter, and if they exist contacts that start with that letter they should be displayed) but I'm not getting the first letter of the vector of names to do this... My attempt to do this is in the SearchContactsByFirstLetter function...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <time.h>
#define MAX_LENGTH 50
typedef struct
{
char name[MAX_LENGTH];
char number[MAX_LENGTH];
int bd;
int bdm;
} ContactBook;
void ListContacts(ContactBook **c, int quant)
{
int i;
printf("\n List of contacts: \n");
printf("\t---------------------\n");
for (i = 0; i < quant; i++)
{
printf("\t%d = birthday: %2d month %2d\t name: %s \t number: %s\n", i + 1, c[i]->bd, c[i]->bdm, c[i]->name, c[i]->number);
}
}
int addContacts(ContactBook **c, int quant, int size)
{
if (quant < size)
{
ContactBook *new = malloc(sizeof(ContactBook));
printf("\nenter contact name: ");
scanf("%49[^\n]", new->name);
printf("\nenter number: ");
scanf("%s", new->number);
printf("\nenter the birthday ");
scanf("%d", &new->bd);
printf("\n enter the month birthday: ");
scanf("%d", &new->bdm);
c[quant] = new;
return 1;
}
else
{
printf("\n full list.\n");
return 0;
}
}
int deleteContact(ContactBook **c, int quant)
{
int id;
ListContacts(c, quant);
printf("\n\t Enter the id you want to delete: \n");
scanf("%d", &id);
id--;
if (id >= 0 && id < quant)
{
free(c[id]);
if (id < quant - 1)
{
c[id] = c[quant - 1];
}
return -1;
}
else
{
printf("\n\t wrong code;\n");
return 0;
}
}
void birthdays(ContactBook **c, int quant)
{
int i;
time_t t = time(NULL);
struct tm tm = *localtime(&t);
printf(" os aniversariantes do mês são: \n");
for (i = 0; i < quant; i++)
{
if (tm.tm_mon + 1 == c[i]->bdm)
{
printf("\t%d = birthday: %2d month %2d\t name: %s \t number: %s\n", i + 1, c[i]->bd, c[i]->bdm, c[i]->name, c[i]->number);
}
}
}
void SearchContactByFirstLetter(ContactBook **c, int quant)
{
int i;
char searchedName[2];
printf("\n Search a letter: \n");
scanf("%s", searchedName);
getchar();
for (i = 0; i < quant; i++)
{
if (strcmp(searchedName, c[i]->name[0]) == 0)
{
printf("\t\nname: %s, \nnumber: %s, \nbirthday: %d \nmonth birthday %d \t\n", c[i]->name, c[i]->number, c[i]->bd, c[i]->bdm);
}
}
}
void SearchContact(ContactBook **c, int quant)
{
int i;
char searchedName[30];
printf("\n Search name: \n");
scanf("%s", searchedName);
getchar();
for (i = 0; i < quant; i++)
{
if (strcmp(searchedName, c[i]->name) == 0)
{
printf("\t\nname: %s, \nnumber: %s, \nbirthday: %d \nmonth birthday %d \t\n", c[i]->name, c[i]->number, c[i]->bd, c[i]->bdm);
}
}
}
void saveBinary(char arquivo[], ContactBook **c, int quant)
{
FILE *file = fopen(arquivo, "wb");
int i;
if (file)
{
for (i = 0; i < quant; i++)
fwrite(c[i], sizeof(ContactBook), 1, file);
fclose(file);
}
else
printf("erro");
}
int readBinaryArq(char arquivo[], ContactBook **c)
{
int quant = 0;
ContactBook *new = malloc(sizeof(ContactBook));
FILE *file = fopen(arquivo, "rb");
if (file)
{
while (fread(new, sizeof(ContactBook), 1, file))
{
c[quant] = new;
quant++;
new = malloc(sizeof(ContactBook));
}
fclose(file);
}
else
printf("\nerro");
return quant;
}
int main()
{
ContactBook *contacts[50];
int option, size = 50, quant = 0;
char arq2[] = ("agenda.dat");
quant = readBinaryArq(arq2, contacts);
do
{
printf(" \n\t0 - exit\n\t1 - register contact\n\t2 - Remove contact\n\t3- List contacts\n\t4- Search contact\n\t5 - ver aniversariantes do mês\n\t6-Pesquisar por inicial\n ");
scanf("%d", &option);
getchar();
switch (option)
{
case 1:
quant += addContacts(contacts, quant, size);
break;
case 2:
quant += deleteContact(contacts, quant);
break;
case 3:
ListContacts(contacts, quant);
break;
case 4:
SearchContact(contacts, quant);
break;
case 5:
birthdays(contacts, quant);
break;
}
saveBinary(arq2, contacts, quant);
} while (option != 0);
return 0;
}
if (strcmp(searchedName, c[i]->name[0]) == 0)
That should be:
if (searchedName[0] == c[i]->name[0])
But you probably shouldn't read in a string in the first place if you only want to read a single character.

I have got a problem with reading binary file into array of structures in c

Here is part of my code:
Here I want to transfer already saved .bin file into a new database structure student s, but it is not transferring more than one member of a structure.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[20];
int date;
int month;
int year;
int id;
int pnum;
}student;
int count = 0;
void swap(student* s1, student* s2) {
student* temp;
temp = s1;
s1 = s2;
s2 = temp;
}
void sort(student* s) {
for (int i = 0; i < count - 1; i++) {
for (int j = i + 1; j < count; j++) {
if (strcmp((s + i)->name, (s + j)->name) > 0) {
student temp = *(s + i);
*(s + i) = *(s + j);
*(s + j) = temp;
}
}
}
}
void addInf(student* s) {
printf("\t==================================Adding information=====================================\n\n");
printf("\t\tPlease input following information: \n");
printf("\tName: ");
scanf("%s", (s + count)->name);
printf("\tDate of birth (yyyymmdd): ");
scanf("%4d%2d%2d", &(s + count)->year, &(s + count)->month, &(s + count)->date);
printf("\tStudent ID: ");
scanf("%d", &(s + count)->id);
printf("\tPhone number: ");
scanf("%d", &(s + count)->pnum);
count++;
printf("\tEntry succeded.\n");
printf("\t=========================================================================================\n\n");
}
void print(student* s) {
printf("\t\tName: %s\n", s->name);
printf("\t\tBidthday: %d/%02d/%02d\n", s->year, s->month, s->date);
printf("\t\tID: %d\n", s->id);
printf("\t\tPhone number: %d\n", s->pnum);
}
void delInf(student* s, int n) {
int com;
printf("\t=================================Deleting information====================================\n\n");
printf("\t=========================================================================================\n\n");
char name[20];
printf("\t\tPlease input name of the student that you want to delete: ");
scanf("%s", &name);
for (int i = 0; i < count; i++) {
if ((strcmp(name, (s + i)->name)) == 0) {
printf("\t\tInformation that you want to delete\n");
print((s + i));
for (int j = i; j < count; j++) {
*(s + i) = *(s + i + 1);
count--;
printf("\t\tInformation was succesfully deleted.\n\n");
}
}
}
}
void searchByID(student* s) {
int key;
printf("\t======================================Searching by ID====================================\n\n");
printf("\t\tEnter ID: ");
scanf("%d", &key);
printf("\t=========================================================================================\n\n");
int i;
for (i = 0; i < count; i++) {
if (key == (s + i)->id) {
break;
}
}
print((s + i));
}
void searchByName(student* s) {
char key[20];
int i;
int size, check = 0;
printf("\t======================================Searching by Name==================================\n\n");
printf("\t\tEnter Name: ");
scanf("%s", &key);
printf("\t=========================================================================================\n\n");
for (i = 0; i < count; i++) {
if (strcmp(key, (s + i)->name) == 0) {
print((s + i));
}
}
}
void searchByBirthDate(student* s) {
int key, command;
int i;
printf("\t================================Searching by Birthdate================================\n\n");
printf("\t\t1.By Date\t\t 2.By Month\t\t 3.By Year\t\t 4.By All\n");
printf("\t\tCommand: ");
scanf("%d", &command);
printf("\t=========================================================================================\n\n");
if (command == 1) {
printf("Enter date: ");
scanf("%2d", &key);
printf("\t\tStudent with same date\n");
for (i = 0; i < count; i++) {
if (key == (s + i)->date) {
printf("\t\t---------%d----------\n\n", i + 1);
print((s + i));
}
}
}
if (command == 2) {
printf("\t\tEnter month: ");
scanf("%2d", &key);
printf("\t\tStudent with same month\n");
for (i = 0; i < count; i++) {
if (key == (s + i)->month) {
printf("\t\t---------%d----------\n\n", i + 1);
print((s + i));
}
}
}
if (command == 3) {
printf("\t\tEnter year: ");
scanf("%4d", &key);
printf("\t\tStudent with same year\n");
for (i = 0; i < count; i++) {
if (key == (s + i)->year) {
printf("\t\t---------%d----------\n\n", i + 1);
print(s + i);
}
}
}
if (command == 4) {
int yy, mm, dd;
printf("\t\tEnter birthdate: ");
scanf("%4d%2d%2d", &yy, &mm, &dd);
for (i = 0; i < count; i++) {
if (yy == (s + i)->year && mm == (s + i)->month && dd == (s + i)->date) {
break;
}
}
print(s + i);
}
}
void printTable(student* s) {
printf("\t============================================Table========================================\n\n");
printf("\t\tName\t\t\tBirthday\t\t\tStudent ID\t\t\tPhone number\n\n");
for (int i = 0; i < count; i++) {
printf("\t%d. %s\t\t\t\t%d/%d/%d\t\t\t%d\t\t\t0%d\n\n", i + 1, (s + i)->name, (s + i)->year, (s + i)->month, (s + i)->date, (s + i)->id, (s + i)->pnum);
}
printf("\t=========================================================================================\n\n");
}
void search(student* s) {
printf("\t=========================================Search==========================================\n\n");
printf("\t\tAvailable commands: \n");
printf("\t\t1. Search by name\t\t\t2. Search by ID\n\t\t3. Search by birthday\n");
printf("\t=========================================================================================\n\n");
printf("\t\tPlease choose command: ");
int com;
scanf("%d", &com);
switch (com) {
case 1: searchByName(s);
break;
case 2: searchByID(s);
break;
case 3: searchByBirthDate(s);
break;
}
}
void menu() {
printf("\n\t======================================MENU===============================================\n");
printf("\t\tAvailable commands: \n");
printf("\t\t1. Add Student\t\t\t2.Delete student\n\t\t3. Find student\t\t\t4. Table of all students\n");
printf("\t\t5. Transfer information from binary file\n\t\t6. Save information into binary file.\n\t\t0. Exit\n\n");
printf("\t=========================================================================================\n\n");
printf("\t\tPlease choose command: ");
}
int main() {
FILE* fp;
FILE* fpr;
printf("\t\tEnter a name of binary file that you want to create: ");
char filename[20];
scanf("%s", &filename);
strcat(filename, ".bin");
fp = fopen(filename, "ab");
if (fp == NULL) {
printf("\t\tUnable to open the file.\nError\n");
exit(1);
}
else printf("\t\t\tFile %s successfuly created\n\n", filename);
int iCount;
int n, c;
student* s;
printf("\t\tPlease enter number of students: ");
scanf("%d", &n);
printf("\n\n");
s = (student*)calloc(n, sizeof(student));
int quit = 1;
while (quit) {
menu();
scanf("%d", &c);
printf("\n");
switch (c) {
case 0:
quit = 0;
break;
case 1:
addInf(&s);
break;
case 2:
delInf(&s, n);
break;
case 3:
search(&s);
break;
case 4:
if (count == 0) printf("\t\tThere is no any given information yet.\n\n");
else printTable(&s);
break;
case 5:
printf("\t\tEnter a name or path of file that you want to open: ");
char readfilename[30];
scanf("%s", &readfilename);
strcat(readfilename, ".bin");
fpr = fopen(readfilename, "rb+");
if (fpr == NULL) {
printf("\t\tUnable to open the file.\nError\n");
break;
}
else printf("\t\tFile %s successfuly opened for reading\n", readfilename);
printf("\t\t\ttransfering binary data from %s into database\n", readfilename);
while ((fread(&s, sizeof(student), 1, fpr)) == 1) {
count++;
}
printf("\t\t%d student information was successfuly transferred\n", count);
break;
case 6:
iCount = fwrite(&s, sizeof(student), count, fp);
if (iCount != count) printf("Information could be missed in %s file\n", filename);
else printf("\t\tAll information was successfuly copied into %s file", filename);
}
sort(&s);
}
fclose(fp);
return 0;
}
First of all, enable warnings when compiling, and follow up on them!
This should tell you that &s is wrong in every place where you used it.
This causes your program to suffer from undefined behavior, which is a total pest when trying to debug your program!
Now then, on to the code that reads students from file:
while ((fread(s, sizeof(student), 1, fpr)) == 1) {
count++;
}
Every student is read into the same memory area (pointed to by s). They overwrite each other, leaving only the last one read. Try s + count instead of s:
while ((fread(s + count, sizeof(student), 1, fpr)) == 1) {
count++;
}

invalid argument read write file

typical beginner's phonebook program, attempting to add read and write to file capabilities. It's not compiling just fine but when I execute either functions 7 or 8, my errorhandler returns "invalid argument"
EDIT* updated code for the whole thing, including several fixes:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct phonebook
{
char cFirstName[20];
char cLastName[20];
char PhoNo[20];
} pb;
//function prototypes
void AddContact (pb * );
void DeleteContact (pb * );
void ShowContacts (pb * );
void FindContact (pb * );
void RandContact (pb * );
void FindContact (pb * );
void DeleteAll (pb *);
void Read (pb *);
void Write (pb *);
char FileName[100];
FILE *pRead;
FILE *pWrite;
int counter = 0;
main ()
{
pb *phonebook;
phonebook = (pb*) malloc(sizeof(pb)*1);
int iChoice = 0;
while (iChoice <= 8)
{
printf("\n-Choose an option- \n");
printf("\n\t(1)\tAdd Contact");
printf("\n\t(2)\tDelete Contact");
printf("\n\t(3)\tShow All Contacts");
printf("\n\t(4)\tSearch for a Contact");
printf("\n\t(5)\tRandom Contact");
printf("\n\t(6)\tDelete All Contacts");
printf("\n\n\t(7)\tWrite contacts to file");
printf("\n\t(8)\tRead contacts from file");
printf("\n\n\t(9)\tExit\n\n\t");
scanf("%d", &iChoice);
if (iChoice == 1)
{
AddContact(phonebook);
}
if (iChoice == 2)
{
DeleteContact (phonebook);
}
if (iChoice == 3)
{
ShowContacts(phonebook);
}
if (iChoice == 4)
{
FindContact(phonebook);
}
if (iChoice == 5)
{
RandContact(phonebook);
}
if (iChoice == 6)
{
DeleteAll(phonebook);
}
if (iChoice == 7)
{
Write(phonebook);
}
if (iChoice == 8)
{
Read(phonebook);
}
if (iChoice == 9)
{
free(phonebook);
return 0;
}
} //end while
} //end main
//function definitions
//add contact
void AddContact (pb * phonebook)
{
counter++; //counter incremented for each entry
realloc(phonebook, sizeof(pb)); //realloc with every new contact
printf("\nFirst Name: ");
scanf("%s", phonebook[counter-1].cFirstName);
printf("Last Name: ");
scanf("%s", phonebook[counter-1].cLastName);
printf("Phone Number: ");
scanf("%s", phonebook[counter-1].PhoNo);
printf("\n\tContact added\n");
}
//delete contact
void DeleteContact (pb * phonebook)
{
int x = 0;
char scrapcFirstName[20]; //strings for deleting original strings
char scrapcLastName[20];
char nullStr[20] = {"\0"};
printf("\nFirst name: ");
scanf("%s", scrapcFirstName);
printf("Last name: ");
scanf("%s", scrapcLastName);
//compare strings
for (x = 0; x < counter; x++)
{
if (strcmp(scrapcFirstName, phonebook[x].cFirstName) == 0)
{
for (x = 0; x < counter; x++)
{
if (strcmp(scrapcLastName, phonebook[x].cLastName) == 0)
{
strcpy(phonebook[x].cFirstName, nullStr);
strcpy(phonebook[x].cLastName, nullStr);
strcpy(phonebook[x].PhoNo, nullStr);
}//end if
else
{
printf("Invalid Input");
}
}//end for
}//end if
} // end for
counter--; // Contact deleted, update counter
printf("Contact Deleted\n");
}
// show phonebook
void ShowContacts (pb * phonebook)
{
int x = 0;
printf("\nPhonebook:\n\n ");
for( x = 0; x < counter; x++)
{
printf("\n(%d)\n", x+1);
printf("Name: %s %s\n", phonebook[x].cFirstName, phonebook[x].cLastName);
printf("Number: %s\n", phonebook[x].PhoNo);
} //end for
}
//Find a specific contact
void FindContact (pb * phonebook)
{
int x = 0;
char TempFirstName[20];
char TempLastName[20];
printf("\nWho are you looking for?");
printf("\n\nFirst Name: ");
scanf("%s", TempFirstName);
printf("Last Name: ");
scanf("%s", TempLastName);
for (x = 0; x < counter; x++)
{
if (strcmp(TempFirstName, phonebook[x].cFirstName) == 0)
{
if (strcmp(TempLastName, phonebook[x].cLastName) == 0)
{
printf("\n%s %s \n%s\n", phonebook[x].cFirstName, phonebook[x].cLastName, phonebook[x].PhoNo);
}
}
}
}
//show a random contact
void RandContact (pb * phonebook)
{
int iRand = 0;
srand(time(NULL));
iRand = rand() % counter;
int x = iRand;
printf("\n%s %s\n", phonebook[x].cFirstName, phonebook[x].cLastName);
printf("%s\n", phonebook[x].PhoNo);
}
//delete all
void DeleteAll (pb * phonebook)
{
int x = 0;
char nullStr[20] = {'\0'};
for ( x = 0; x < counter; x++ )
{
strcpy(phonebook[x].cFirstName, nullStr);
strcpy(phonebook[x].cLastName, nullStr);
strcpy(phonebook[x].PhoNo, nullStr);
--counter;
}
printf("Contacts have been wiped.\n");
}
void Read(pb * phonebook)
{
FILE *pRead;
char name[256];
printf("File to read: ");
gets(name);
pRead=fopen(name,"a");
if(pRead != NULL)
{
printf("Contact List");
while(!feof(pRead)){
fread(phonebook, sizeof (struct phonebook), 1, pRead);
fclose(pRead);
if (!feof(pRead)){
fread(phonebook, sizeof (struct phonebook), 1, pRead);
fclose(pRead);
}
}
}
else{
goto ErrorHandler;
}
exit(EXIT_SUCCESS);
ErrorHandler:
perror("The following error occured");
exit(EXIT_FAILURE);
}
void Write(pb * phonebook)
{
FILE *pWrite;
char name[256];
printf("File to write:");
gets(name);
pWrite=fopen(name,"a");
if(pWrite != NULL)
{
fwrite(phonebook, sizeof (struct phonebook), 1, pRead);
fclose(pWrite);
}
else{
goto ErrorHandler;
}
exit(EXIT_SUCCESS);
ErrorHandler:
perror("The following error occured");
exit(EXIT_FAILURE);
}
It's still giving me the same error, "invalid argument"
In read function you have used pWrite instead of pRead
pWrite=fopen(name,"a");
And checking for EOF condition for pRead
while(!feof(pRead))
The file name is not being set: char name[256]; and then fopen(name,"a") that's why fopen fails.
Apparently gets() does not work after your scanf, correct your scanf on line 49: to scanf("%d\n"
Input in C. Scanf before gets. Problem
The other problems have been already pointed out (*pRead instead of *pWrite), not closing files etc.

can't parse next word in char array using strtok

#include"shell.h"
int main()
{
char cInput[50];
char cCopy[50];
char *pCommand;
char pArguement[10];
bool bRun = true;
while(strcmp(pCommand, "exit"))//run untill exit
{
printf("[myshell]%% ");
cin >> cInput; //get command from user
for(int i=0; i<50; i++)
cCopy[i] = cInput[i];
//get command
pCommand = strtok(cInput, " ");
if(!strcmp(pCommand, "pwd"))
{
printf("No FUNCTIONAILITY FOR PWD! \n");
}
else if(!strcmp(pCommand, "list"))
{
printf("No FUNCTIONAILITY FOR LIST! \n");
}
else if(!strcmp(pCommand, "history"))
{
printf("No FUNCTIONAILITY FOR HISTORY! \n");
}
else if(!strcmp(pCommand, "prompt"))
{
// pCommand = strtok(cCopy, "y");
while(pCommand != NULL)
{
printf(" %s \n", pCommand);
pCommand = strtok(NULL, " ");
}
return 0;
}
else//command not found
{
printf("%s: Command not found \n", pCommand);
}
}
return 0;
}
So I'm trying to follow the example of strtok from the C standard library, but I can't figure out why I'm unable to get the next word from the cstring cInput. I was under the impression that using:
while(pCommand != NULL)
{
printf(" %s \n", pCommand);
pCommand = strtok(NULL, " ");
}
would result in getting the next words.
Any help?
Thanks!

Sorting array filled with lines of string

I have a data in text like this:
1,jack,3,7.3
2,mike,4,8.6
3,gol,2,9
Could any one help me how to sort the data by the last column that represent the grades in descending using c language?
The question was posted before but with no code so I posted it again to get more help.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
int cid;
char name[40];
char term[2];
double gpa;
}student;
typedef struct
{
char line[300];
}data;
typedef struct
{
int cid;
}finds;
typedef struct
{
double score;
}gpa;
void menu();
int calculateMax(void);
void addStudent();
void find();
void display();
void sort();
int main()
{
menu();
system("PAUSE");
return 0;
}
void menu()
{
int selection;
printf("%s", "Program menu :\n");
printf("%s", "1. Add a new student\n");
printf("%s", "2. Find/retrieve information for a particular Student\n");
printf("%s", "3. Display STUDENTS list\n");
printf("%s", "4. Find a student that has the lowest and the highest deposit\n");
printf("%s", "5. Quit\n");
printf("%s", "Selection : ");
scanf("%d", &selection);
if(selection == 1)
{
addStudent();
}
else if(selection == 2)
{
find();
}
else if(selection == 3)
{
display();
}
else if(selection == 4)
{
sort();
}
else if(selection == 5)
{
exit(0);
}
else {
printf("%s", "\n\aError, please key in correct input!\n\n");
menu();
}
}
void addStudent()
{
int max, i;
FILE *f, *id, *name, *term, *gpa , *sort;
printf("%s", "\n\nADD student\n");
printf("%s", "How many students you would like to add : ");
scanf("%d", &max);
student *student_info;
student_info = (student *) malloc(max * sizeof(student)); /*Allocate Memory For Client's Info*/
if(student_info == NULL)
{
printf("Unable to allocate space for client\n\n");
exit (EXIT_FAILURE);
}
if ((id = fopen("id.txt", "a+")) == NULL) /*Open file id.txt*/
{
printf("Error, the file cannot be opened\n");
}
if ((name = fopen("name.txt", "a+")) == NULL) /*Open file name.txt*/
{
printf("Error, the file cannot be opened\n");
}
if ((term = fopen("term.txt", "a+")) == NULL) /*Open file TERM.txt*/
{
printf("Error, the file cannot be opened\n");
}
if ((gpa = fopen("gpa.txt", "a+")) == NULL) /*Open file GPA.txt*/
{
printf("Error, the file cannot be opened\n");
}
if ((f = fopen("student.txt", "a+")) == NULL) /*Open file STUDENTS.txt*/
{
printf("Error, the file cannot be opened\n");
}
if ((sort = fopen("sort.txt", "a+")) == NULL) /*Open file SORT.txt*/
{
printf("Error, the file cannot be opened\n");
}
else {
for (i = 0; i < max ; i++) { /*Get the input data*/
printf("student %d\n", i + 1);
printf("%s", "student's Id : ");
scanf("%5d", &student_info[i].cid);
printf("%s", "student's Name : ");
fflush(stdin);
gets(student_info[i].name);
printf("%s", "student's term : ");
fflush(stdin);
gets(student_info[i].term);
printf("%s", "student's GPA : ");
scanf("%7lf", &student_info[i].gpa);
printf("\n");
}
}
for(i = 0; i < max; i++) { /*Store input data into files*/
fprintf(id, "%d\n", student_info[i].cid);
fputs(student_info[i].name, name);
fprintf(name, "\n");
fputs(student_info[i].term, term);
fprintf(term, "\n");
fprintf(gpa, "%lf\n", student_info[i].gpa);
fprintf(sort,"%d,%s,%s,%lf\n",student_info[i].cid,student_info[i].name,student_info[i].term,student_info[i].gpa);
}
for(i = 0; i < max; i++) {
fprintf(f, "%d", student_info[i].cid, "");
fprintf(f, "%3s", "");
fputs(student_info[i].name, f);
fprintf(f, "%5s", "");
fputs(student_info[i].term, f);
fprintf(f, "%7s", "");
fprintf(f, "%lf\n", student_info[i].gpa);
}
fclose(f);
fclose(id);
fclose(name);
fclose(term);
fclose(gpa);
fclose(sort);
free(student_info);
student_info = NULL;
printf("\n");
menu();
}
void find()
{
int find_id = 0, i = 0, student_cid, n = 0, max, selection;
FILE *id, *f;
max = calculateMax();
finds *result;
result = (finds *) malloc(max * sizeof(finds));
if(result == NULL)
{
printf("Unable to allocate space for student\n\n");
exit (EXIT_FAILURE);
}
if ((id = fopen("id.txt", "r")) == NULL)
{
printf("Error, the file cannot be opened\n");
}
else {
while (!feof(id)) { /*Get all clients' id number and store to array*/
fscanf(id, "%d", &result[i].cid);
i++;
}
}
fclose(id);
printf("%s", "\n\nFIND STUDENT\n");
printf("%s", "Key in Student's id : "); /*Get the client's id that user want to query*/
scanf("%d", &student_cid);
data *student_info;
student_info = (data *) malloc(max * sizeof(data));
if(student_info == NULL)
{
printf("Unable to allocate space for student\n\n");
exit (EXIT_FAILURE);
}
if ((f = fopen("student.txt", "r")) == NULL)
{
printf("Error, the file cannot be opened\n");
}
i = 0;
while (!feof(f)) { /*Get all the students' data from clients.txt and stored to array*/
fflush(stdin);
fgets(student_info[i].line, 300, f);
i++;
}
fclose (f);
for(i = 0; i < max + 1; i++)
{
if(student_cid == result[i].cid)
{
printf("\n\n%s%6s%20s%17s\n", "ID", "NAME", "TERM", "GPA");
puts(student_info[i].line);
free(student_info);
student_info = NULL;
free(result);
result = NULL;
printf("Would you like to find another student?\nKey in 1 for yes or 2 to go to menu : ");
scanf("%d",&selection);
if(selection == 1) {
find();
}
else if(selection == 2) {
menu();
}
break;
}
else if(i == max)
{
printf("\nSory, there's no student with that exist in database.\n");
free(student_info);
student_info = NULL;
free(result);
result = NULL;
printf("Would you like to find another student?\nKey in 1 for yes or 2 to go to menu : ");
scanf("%d",&selection);
if(selection == 1) {
find();
}
else if(selection == 2) {
printf("\n\n");
menu();
}
}
}
}
void display()
{
int max = 0, i;
FILE *f;
printf("\n\nDISPLAY STUDENT");
max = calculateMax();
data *student_info;
student_info = (data *) malloc(max * sizeof(data));
if(student_info == NULL)
{
printf("Unable to allocate space for student\n\n");
exit (EXIT_FAILURE);
}
if ((f = fopen("student.txt", "r")) == NULL)
{
printf("Error, the file cannot be opened\n");
}
i = 0;
while (!feof(f)) {
fflush(stdin);
fgets(student_info[i].line, 200, f);
i++;
}
fclose (f);
printf("\n\n%s%6s%20s%17s\n", "ID", "NAME", "TERM", "GPA");
for(i = 0; i < max; i++)
{
puts(student_info[i].line);
}
free(student_info);
student_info = NULL;
}
int calculateMax(void)
{
char str[150];
int maximum = 0;
FILE *f;
if ((f = fopen("student.txt", "r")) == NULL)
{
printf("Error, the file cannot be opened\n");
}
else {
while (!feof(f)) {
maximum++;
fgets (str , 200 , f);
}
}
fclose (f);
maximum = maximum - 1;
return maximum;
}
////////////////////////////////////////////////////////////////////
static int student_info_compare(const void *a, const void *b)
{
const student_info *sia = a, *sib = b;
return strcmp(sia->name, sib->name);
}
void Sortdisplay()
{
int max = 0, i;
FILE *f;
printf("\n\nDISPLAY SORTED STUDENT");
max = calculateMax();
data *student_info;
student_info = (data *) malloc(max * sizeof(data));
if(student_info == NULL)
{
printf("Unable to allocate space for student\n\n");
exit (EXIT_FAILURE);
}
if ((f = fopen("sort.txt", "r")) == NULL)
{
printf("Error, the file cannot be opened\n");
}
i = 0;
while (!feof(f)) {
fflush(stdin);
fgets(student_info[i].line, 200, f);
i++;
}
fclose (f);
printf("\n\n%s%6s%20s%17s\n", "ID", "NAME", "TERM", "GPA");
student_info_compare();
for(i = 0; i < max; i++)
{
// iwant to sort here
qsort(student_info, max, sizeof student_info[0], student_info_compare);
puts(student_info[i].line);
}
free(student_info);
student_info = NULL;
}
Try this:
static int student_info_compare(const void *a, const void *b)
{
const student_info *sia = a, *sib = b;
return strcmp(sia->name, sib->name);
}
then add this before the print loop:
qsort(student_info, max, sizeof student_info[0], student_info_compare);
This uses the standard qsort() function to sort the array. The student_info_compare() function serves as the comparison-callback, since qsort() doesn't know how your data looks.
The arguments to the comparison-callback have type const void *, which basically means "here's a pointer to something whose exact type is not known, and you're supposed to treat it as a read-only pointer". That's how qsort() passes pointers to the array elements, since (again) it doesn't know that they are of type const student_info *.

Resources