Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

C program debugging. I need help debugging this program #include <stdlib.h> #inc

ID: 3854341 • Letter: C

Question

C program debugging. I need help debugging this program

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

typedef enum {
   PaperBack;
   HardBack;
} Type;

typedef struct book {
   char* name;
   char* author;
   int rating;
   Type type;
} Book;

typedef Book* Library;

Library loadLibrary(const char* filename, int* lenPtr);
void sortLibrary(Library library, int length);
void printLibrary(Library library, int length);
void writeLibrary(Library library, int length, const char* filename);

int main(int argc, char* argv[]) {
   if (argc < 3) {
       printf("Incorrect Usage ");
       printf("%s <input file> <output file> ", argv[0]);
       return 0;
   }

   int* length;
   Library library = loadLibrary(argv[1], length);
  
   sortLibrary(library, length);
   printLibrary(library, length);
   writeLibrary(library, length, argv[0]);

   free(library);
  
   int i;
   for (i = 0; i < length; i++)
       free(library[i].name);
       free(library[i].author)
  

   return 0;
}

Library loadLibrary(const char* filename, int* lenPtr) {
   FILE* fp = fopen(filename, "r");
   if (fp == NULL) {
       printf("Failed to open file %s ", filename);
       *lenPtr = 0;
       return NULL;
   }

   fscanf(fp, "%d", lenPtr);
   Library library = malloc(sizeof(Book) * lenPtr);

   int i;
   for (i = 0; i < *lenPtr; i++) {
       fscanf(fp, "%s %s %d", library[i].name, library[i].author, &library[i].rating, &library[i].type);
   }

   return library;
   fclose(fp);
}

void sortLibrary(Library library, int length) {
   int i;

   for (i = 1; i < length; i++) {
       int j = i;
       while (j > 0 && library[j].rating < library[j - 1].rating); {
           Book temp = library[j];
           library[j] = library[j - 1];
           library[j - 1] = temp;
       }
   }
}

void printLibrary(Library library, int length) {
   int i;
   for (i = 0; i < length; i++) {
       printf("%s %s %d", library[i].name, library[i].author, library[i].rating);
       if (library.type = PaperBack) {
           printf(" PaperBack ");
       } else {
           printf(" HardBack ");
       }
   }
}

void writeLibrary(Library library, int length, const char* filename) {
   FILE* fp = fopen(filename, "w");
   if (fp == NULL) {
       return ;
   }

   fprintf(fp, "%d ", length);

   int i;
   for (i = 0; i < length; i++) {
       fprintf(fp, "%s %s %d %d ", library[i].name, library[i].author, library[i].rating, library[i].type);
   }

   fclose(fp);
}

Explanation / Answer

I have fixed your code and tested with sample input file. I have shown in bold the fixed part. If any issues, please post a comment and I shall respond. If happy with the answer , please rate it. Thank you.

---------

The input file should contain the number of records in the 1st line, followed by the records. Please keep in mind that book name and author can only be single words each. So you can not write a book name like Java Programming with a space in between. This is because you are using fscanf in your code and using that spaces will not be allowed in string. Space will be delimiter. Since your are using space to delimiit fields in your record, you will have to enter only single word for book name. Same is the case with author.

If you would like to include spaces in name and author , you should use some other field separator like comma . Example

Java Programming,Joshua Bloch,4,0

In this case you will need to fgets() to read a line from the file and then separate tokens using strtok() function.

--------

Fixed code below. Fixes are

1. remove ; for each item in the enum. Use only a comma for every item . No comma after last one
2. change declaration of length . Instead of pointer, make it just int , and then pass its address to loadLibrary() using &length.
3. The lines to free name, author enclosed in { } of for loop.
4. During allocation of memory using malloc() ,use *lenPtr to get the contents (int value) in the location pointed by lenPtr
5. While loading from file, the fscanf() should include another %d for reading the type
6. The return statement should come after fclose() in loadLibrary. Once the return is done, no other statements in the function get executed
7. Fixed the code in sortLibrary()
8. In printLibrary() , use the index to access the library element for checking if its PaperBack, also use == for comparsion
9. In main() , free(library) should be written after all name and authors are freed.
10. In main(), while passing output filename to writeLibrary(), use argv[2] to get the outfile name command line argument
11. While loading from file, the fscanf() should read name and author in a char array and then allocate needed space in library and copy the values

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

typedef enum {

PaperBack,

HardBack

} Type;

typedef struct book {

char* name;

char* author;

int rating;

Type type;

} Book;

typedef Book* Library;

Library loadLibrary(const char* filename, int* lenPtr);

void sortLibrary(Library library, int length);

void printLibrary(Library library, int length);

void writeLibrary(Library library, int length, const char* filename);

int main(int argc, char* argv[]) {

if (argc < 3) {

printf("Incorrect Usage ");

printf("%s <input file> <output file> ", argv[0]);

return 0;

}

int length;

Library library = loadLibrary(argv[1], &length);

  

sortLibrary(library, length);

printLibrary(library, length);

writeLibrary(library, length, argv[2]);

  

  

int i;

for (i = 0; i < length; i++)

{

free(library[i].name);

free(library[i].author);

}

  

free(library);

return 0;

}

Library loadLibrary(const char* filename, int* lenPtr) {

FILE* fp = fopen(filename, "r");

if (fp == NULL) {

printf("Failed to open file %s ", filename);

*lenPtr = 0;

return NULL;

}

fscanf(fp, "%d", lenPtr);

Library library = (Library)malloc(sizeof(Book) * (*lenPtr));

char name[30], author[20];

int i;

for (i = 0; i < *lenPtr; i++) {

  

fscanf(fp, "%s %s %d %d", name , author, &library[i].rating, &library[i].type);

  

//allocate memory for the name and author in library[i] and copy hte values

library[i].name = malloc(strlen(name));

strcpy(library[i].name , name);

  

library[i].author = malloc(strlen(author));

strcpy(library[i].author , author);

}

  

fclose(fp);

return library;

}

void sortLibrary(Library library, int length) {

int i;

for (i = 0; i < length; i++) {

int j = 0;

while (j < length - i - 1 )

{

if(library[j].rating > library[j + 1].rating){

Book temp = library[j];

library[j] = library[j + 1];

library[j + 1] = temp;

  

}

j++;

}

}

}

void printLibrary(Library library, int length) {

int i;

for (i = 0; i < length; i++) {

printf("%s %s %d", library[i].name, library[i].author, library[i].rating);

if (library[i].type == PaperBack) {

printf(" PaperBack ");

} else {

printf(" HardBack ");

}

}

}

void writeLibrary(Library library, int length, const char* filename) {

FILE* fp = fopen(filename, "w");

if (fp == NULL) {

return ;

}

fprintf(fp, "%d ", length);

int i;

for (i = 0; i < length; i++) {

fprintf(fp, "%s %s %d %d ", library[i].name, library[i].author, library[i].rating, library[i].type);

}

fclose(fp);

}

sample input file: library.txt

2
JavaProgramming Joshua 4 1
Networking Stephen 3 0

output

Networking Stephen 3 PaperBack

JavaProgramming Joshua 4 HardBack