-1

How to have a program that uses the pointer ptr for reading and printing stuff about a book struct without using any other variable. For the access to the stuff of the struct i have to use the -> My program terminates after the first read. Can somebody provide me with a code? Here is my code :

#include<stdio.h>

struct book {
    char title[100];
    char authors;
    int code;
    double prc;
};

int main(void) {
    struct book *ptr;
    printf("Title:\n");
    gets(&ptr->title[100]);
    printf("authors:\n");
    gets(&ptr->authors);
    printf("code:\n");
    scanf("%d",&ptr->code);
    printf("Price:\n");
    scanf("%lf",&ptr->prc);

    printf("T:%s,A:%s,C:%d,P:lf\n",ptr->title,ptr->authors,ptr->code,ptr->prc);
    return 0;
}

I expect the program to read these 4 things about a book and then prints them in the final printf using only the pointer ptr

klutt
  • 30,332
  • 17
  • 55
  • 95
Johny21111
  • 15
  • 5
  • Allocate you book or do not use a pointer placing it in the stack. do not use _gets_, use _fgets_ to limit the size, verify your _scanf_ return 1 to check the user enter a valid input. – bruno May 25 '19 at 15:06
  • Never use [gets](http://man7.org/linux/man-pages/man3/gets.3.html), its usage is depreciated. Use `fgets()` instead. – Achal May 25 '19 at 15:06
  • 1
    Also this `&ptr->title[100]` is wrong. Since `title` is character buffer, its name itself address, use `scanf("%s", ptr->title);` or `fgets(ptr->title, sizeof(ptr->title), stdin);` and check the return value of `fgets()` or `scanf()` whichever you are going to use.. – Achal May 25 '19 at 15:08

2 Answers2

1

You have to allocate memory first.

struct book *ptr = malloc(sizeof (*ptr));

Also, never use the function gets. It have been removed. Read here why it is dangerous

Besides, the call to gets is wrong. The argument should be ptr->title. But use this instead:

fgets(ptr->title, 100, stdin);

And always check the return value from scanf to ensure everything went ok.

klutt
  • 30,332
  • 17
  • 55
  • 95
  • @Achal Not really necessary for small programs, and I think the answer becomes to broad if I would address all the flaws. – klutt May 25 '19 at 15:18
1

You have several problems

  • you missed to allocate your instance of book

  • &ptr->title[100] is invalid

  • the use of gets is deprecated since years, use fgets to limit the size and avoid undefined behavior

  • you missed to check your scanf return 1 to know if a valid input was done

  • you have a memory leak because of the malloc without a free, and in fact you do not need to allocate your book in the heap

  • are you sure just a char is enough for authors ? probably you wanted an array

  • gets(&ptr->authors); is invalid because authors is just a character

  • the format "%s" for authors is invalid because it is just a character

  • you missed a % before "lf" to print the price

Probably you do not want the newline in the input string

You wanted something like :

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

struct book {
    char title[100];
    char authors[100];
    int code;
    double prc;
};

int main(void) {
    struct book * ptr = malloc(sizeof(struct book));
    size_t len;

    printf("Title:\n");
    if (fgets(ptr->title, sizeof(ptr->title), stdin) == NULL)
      /* EOF */
      return -1; /* or an other behavior is you want */
    len = strlen(ptr->title);
    if (ptr->title[len - 1] == '\n')
      ptr->title[len - 1] = 0;
    printf("authors:\n");
    if (fgets(ptr->authors, sizeof(ptr->authors), stdin) == NULL)
      /* EOF */
      return -1;/* or an other behavior is you want */
    len = strlen(ptr->authors);
    if (ptr->authors[len - 1] == '\n')
      ptr->authors[len - 1] = 0;
    printf("code:\n");
    if (scanf("%d",&ptr->code) != 1) {
      puts("invalid code");
      return 1; /* or an other behavior is you want */
    }
    printf("Price:\n");
    if (scanf("%lf",&ptr->prc) != 1) {
      puts("invalid price");
      return 1; /* or an other behavior is you want */
    }

    printf("T:%s,A:%s,C:%d,P:%lf\n",ptr->title,ptr->authors,ptr->code,ptr->prc);

    free(ptr);

    return 0;
}

or without allocating the book in the heap :

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

struct book {
    char title[100];
    char authors[100];
    int code;
    double prc;
};

int main(void) {
    struct book b;
    size_t len;

    printf("Title:\n");
    if (fgets(b.title, sizeof(b.title), stdin) == NULL)
      /* EOF */
      return -1; /* or an other behavior is you want */
    len = strlen(b.title);
    if (b.title[len - 1] == '\n')
      b.title[len - 1] = 0;
    printf("authors:\n");
    if (fgets(b.authors, sizeof(b.authors), stdin) == NULL)
      /* EOF */
      return -1;/* or an other behavior is you want */
    len = strlen(b.authors);
    if (b.authors[len - 1] == '\n')
      b.authors[len - 1] = 0;
    printf("code:\n");
    if (scanf("%d",&b.code) != 1) {
      puts("invalid code");
      return 1; /* or an other behavior is you want */
    }
    printf("Price:\n");
    if (scanf("%lf",&b.prc) != 1) {
      puts("invalid price");
      return 1; /* or an other behavior is you want */
    }

    printf("T:%s,A:%s,C:%d,P:%lf\n",b.title,b.authors,b.code,b.prc);

    return 0;
}

Compilation and execution :

pi@raspberrypi:/tmp $ gcc -pedantic -Wall -Wextra c.c
pi@raspberrypi:/tmp $ ./a.out
Title:
the mirific title
authors:
me
code:
007
Price:
12.34
T:the mirific title,A:me,C:7,P:12.340000
pi@raspberrypi:/tmp $ 
bruno
  • 32,421
  • 7
  • 25
  • 37