0
this output

Andrew Tanenbaum, David Wetherall
    Computer Networks
    Michaell Donahoo, Kenneth Calvert
    TCP/IP Sockets in C
    William,Stallings
    Yale Patt, Sanjay Patel

is the result of this code.




#include <stdio.h>      /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket() and bind() */
#include <arpa/inet.h>  /* for sockaddr_in and inet_ntoa() */
#include <stdlib.h>     /* for atoi() and exit() */
#include <string.h>     /* for memset() */
#include <unistd.h>     /* for close() */
#include "./book.h"
#ifndef fileget_C
#define fileget_C
#endif // fileget_C

 void readlib(Book* Library){
/*char stock[4][125];*/
  FILE *bookfile=fopen("/home/ninja/Sockets/bookstock.txt","r+");


  size_t len=0;
  int num;
  ssize_t read;
  char *stringin;
  char *isbn;
  int *numin;

int n;
  for(n=0; n<4; n=n+1){
  getline(&stringin, &len, bookfile);
  strncpy(Library[n].isbn,stringin,strlen(stringin));
  //printf("%s",Library[n].isbn);
  stringin=NULL;

  getline(&stringin, &len, bookfile);
  strncpy(Library[n].Author,stringin,strlen(stringin));
  //printf("%s",Library[n].Author);
  stringin=NULL;

  getline(&stringin, &len, bookfile);
  strncpy(Library[n].title,stringin,strlen(stringin));
  //printf("%s",Library[n].title);
  stringin=NULL;

  getline(&stringin, &len, bookfile);
  num=atoi(stringin);
  Library[n].edition=num;
  //printf("%d\n",Library[n].edition);
  stringin=NULL;

  getline(&stringin, &len, bookfile);
  Library[n].year=atoi(stringin);
  stringin=NULL;
  //printf("%d\n",Library[n].year);

  getline(&stringin, &len, bookfile);
  strncpy(Library[n].publisher,stringin,strlen(stringin));
  stringin=NULL;


  getline(&stringin, &len, bookfile);
  Library[n].inventory=atoi(stringin);
  stringin=NULL;

  getline(&stringin, &len, bookfile);
  Library[n].available=atoi(stringin);
  //printf("%d\n",Library[n].available);

  }
 // printf("%s",Library[0].title);
  //printf("%s",Library[1].title);
  //printf("%s",Library[2].title);
  //printf("%s\n",Library[3].title);

  printf("%s",Library[0].Author);
  printf("%s",Library[1].Author);
  printf("%s",Library[2].Author);
  printf("%s",Library[3].Author);



}

For some reason, I'm getting extra lines stored or I am not storing to the pointer in an appropriate way. The commented out print lines in the for loop display the right information which includes printing the appropriate author field of the struct.

Mike
  • 7
  • 1
  • 1
    The error message says you're returning a pointer to a local variable. It's odd that the compiler isn't objecting to the implicit return type is `int` since you don't show any return type. You could use `malloc()` or one of its relatives to allocate an array of structures and return the pointer to that: `Book *readlib(const char *filename)` would be a signature (don't hard code the file name either). Or the caller can pass an array of structures to the function: `size_t readlib(const char *filename, Book *library, size_t libsize)` (`libsize` is the array size; return the number of books). – Jonathan Leffler Feb 19 '16 at 06:14
  • BTW: `strncpy(Library[n].isbn,stringin,strlen(stringin));` is wrong. (using strncpy() is almost always wrong) – wildplasser Feb 20 '16 at 13:59

1 Answers1

2

The problem is with your readlib() and your Library.

Note that the return of the readlib() is not of type Book*, while you return Library which is of type Book[], thus the compiler gives you the warning.

Also, it seems like you are trying to return an array in C. Be very careful. Technically, you could change the return of readlib() like this:

Book* readlib()

But it is highly not recommended. It is better to have array declared outside of the function and the function contains the Book* argument in it:

void readlib(Book* Library, int noOfBook)

Then you declare your

Book Library[4]; //somewhere else

and call the readlib like this:

readlib(Library, 4);

You do not need to to:

return Library; 

In the readlib, since it is already declared outside and passed to the readlib

Of course, if you really want to return Book* however, you could prepare proper memory space by using malloc in the function:

Book* readlib(int noOfBook){
    Book *Library = malloc (noOfBook * sizeof(Book));
    //something else
    return Library;
}

But I personally prefer to handle all these outside.

Community
  • 1
  • 1
Ian
  • 30,182
  • 19
  • 69
  • 107
  • You could also declare `Book * readlib()` and dynamically allocate `Library` (e.g. `Book *Library = malloc (4 * sizeof *Library);`) and then return a pointer to `Library` (e.g. `return Library;`) – David C. Rankin Feb 19 '16 at 06:14
  • @DavidC.Rankin ah, yes. using `malloc`, that will be a lot more proper if we want to return `Book*` – Ian Feb 19 '16 at 06:15
  • Either way is fine - e.g. pass `Book *Library` as a parameter or dynamically allocate. It all depends if you need to grow `Library` later with `realloc`. If not, passing it as a parameter (along with its max size) is probably more efficient `:)` – David C. Rankin Feb 19 '16 at 06:17
  • @DavidC.Rankin yeah. `:)` perhaps, I am more towards the parameter passing option together with its `maxSize`. Not sure if this is considered old-fashioned? :) – Ian Feb 19 '16 at 06:21
  • 1
    No, it's not old fashioned at all. Statically allocated storage provides faster access and does not require the function call overhead that `malloc`/`calloc`/`free` does. It's is a trade off. If you know you `max` size before hand, the static passing is a better option. If you don't, then you need to dynamically allocate and keep track of the allocation size and `realloc` as required. Just a matter of tailoring the code to the particular problem at hand. – David C. Rankin Feb 19 '16 at 06:34
  • If I were to pass down the reference to library as a pointer in arguments, would it create a new instance or would it being modifying the instance of the array in the c file that called to it. – Mike Feb 19 '16 at 14:15
  • @Mike it will create new pointer, *but* the new pointer will point to the *same* instance as the pointer in the caller file. Thus, you do *not* create new instance of *Book*, You create new *pointer* which point to the same *Book* instances. – Ian Feb 20 '16 at 00:13