0

what is mistake ? i cant find any mistake in my code but it does not take input properly and it also displays some garbage values. Thanks:

int main()
{
    struct book
    {
        char name;
        int price;
        int pages;
    };
    struct book b[5];
    int i;

    for (i = 0; i < 5; i++)
    {
        printf("enter name price pages\n");
        scanf("%c", &b[i].name);
        scanf("%d", &b[i].price);
        scanf("%d", &b[i].pages);
    }
    for (i = 0; i < 5; i++)
        printf("%c %d %d\n", b[i].name, b[i].price, b[i].pages);
    return 0;
}
lurker
  • 56,987
  • 9
  • 69
  • 103
Aj Jadoon
  • 31
  • 5
  • 1
    You sure you didn't mean to use `char*` instead of `char`, or do you only require one character? – user123 Dec 06 '13 at 16:17
  • 2
    You are aware, presumably, that `book` at present can only have a single letter name. – Bathsheba Dec 06 '13 at 16:17
  • 1
    @MohammadAliBaydoun: it probaby should be `char name[32];` or something similar — at least for a person asking this level of C question. Dynamic memory allocation comes later. – Jonathan Leffler Dec 06 '13 at 16:22

5 Answers5

3

Most books have a name that is longer than a single letter.

You need to adjust the structure accordingly:

enum { MAX_BOOKNAMELEN = 32 }; // Probably too short

struct book
{
    char name[MAX_BOOKNAMELEN];
    int price;
    int pages;
};

You also need to adjust the input:

    if (scanf("%31[^\n]", b[i].name) != 1)
        ...report error; do not use this book entry...

The '31' is magicked out of thin air; it is one less than MAX_BOOKNAMELEN. Note that book titles frequently contain spaces; thus %s which skips leading spaces and stops at the first space after one or more non-space characters is not appropriate for reading titles. One way to create the format string is via sprintf() — this will adapt if MAX_BOOKNAMELEN changes size:

char name_fmt[16];
snprintf(name_fmt, sizeof(name_fmt), "%%%d[^\n]", MAX_BOOKNAMELEN-1);

if (scanf(name_fmt, b[i].name) != 1)
    ...error...

A more thorough revision would probably use fgets() and sscanf() or other tools instead of calling scanf() directly.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • i am only ussing single charcter for word but still thers problem – Aj Jadoon Dec 06 '13 at 16:25
  • If you really mean to support just 256 different possible book titles, then I suppose [Mohamed](http://stackoverflow.com/users/1003575/mohamed) has given you the necessary [answer](http://stackoverflow.com/a/20428585/15168). However, one-letter book titles will pall after a while; then you can come back to the techniques in this answer. – Jonathan Leffler Dec 06 '13 at 16:27
  • Thanks, Eric Postpischil. – Jonathan Leffler Dec 06 '13 at 16:28
2

this line

scanf("%c",&b[i].name);

should be

scanf(" %c",&b[i].name);

See How to do scanf for single char in C

Community
  • 1
  • 1
MOHAMED
  • 41,599
  • 58
  • 163
  • 268
  • @Bathsheba Read this post http://stackoverflow.com/questions/13542055/in-c-how-to-do-scanf-for-single-char – EmptyData Dec 06 '13 at 16:24
1

Since I've been informed to specifically answer the question (sorry, Im new here), the problem lies in the %c picking up whitespace and/or newline characters. The easiest way to prevent this is put a " " in front of it.

#include <stdio.h>

int main()
{
    struct book
    {
        char name; 
        int price;
        int pages;
    };

    struct book b[5];
    int i;
    for(i=0;i<5;i++)
    {
        printf("enter name price pages\n");
        scanf(" %c %d %d",&b[i].name, &b[i].price, &b[i].pages);  //here
        //%c was grabbing whitespace and/or newline causing the problem.
    }
    for(i=0;i<5;i++)
        printf("Name:  %c Price:  %d Pages:  %d\n",b[i].name,b[i].price,b[i].pages);

    return 0;
}

Output:

enter name price pages

a 1 2

enter name price pages

b 3 4

enter name price pages

c 5 6

enter name price pages

d 7 8

enter name price pages

e 9 10

Name: a Price: 1 Pages: 2

Name: b Price: 3 Pages: 4

Name: c Price: 5 Pages: 6

Name: d Price: 7 Pages: 8

Name: e Price: 9 Pages: 10

wbt11a
  • 798
  • 4
  • 12
0

What happens is that the last scanf("%d"), reads the number and let a '\n' at the buffer, so next time you call scanf("%c"), it will read the '\n' in the buffer, and not the new character.

One possible solution to use scanf, is to tell scanf to read everything in the line, and discard it:

    scanf("%c%*[^\n]\n", &b[i].name);
    scanf("%d%*[^\n]\n", &b[i].price);
    scanf("%d%*[^\n]\n", &b[i].pages);

This way, scanf will block until you press enter, and will read the '\n'.

Jonatan Goebel
  • 1,107
  • 9
  • 14
0

try it like this :

scanf(" %c %d %d",&b[i].name, &b[i].price, &b[i].pages);
while(getchar()!='\n');
thrax
  • 365
  • 2
  • 3
  • 10