1

Recently, I took a subject called Data structure. I've created a program to try out my knowledge but don't know why the program did not work. I can't figure it out so I post it here to ask for solution. I hope people can help me. I am newbie here. So please ignore my opinion if my opinion is found annoying.

#include <stdio.h>
int main()
{
    struct Book
    {
        char title[50];
        int year;
        float price;
    };
    int i;

    struct Book books[50];
    books[0].title="Bullshit";
    books[0].year=132;
    books[0].price=146.9;

    books[1]=(struct Book){"Money",1344,189.4
    };

    for(i=0;i<2;i++)
    {
        printf("Book Title is : %s\n",books[i].title);
        printf("Book Year is %d\n",books[i].year);
        printf("Book price is %3.2f\n",books[i].price);
        printf("\n\n");
    }
}
J K
  • 632
  • 7
  • 24
TeoPeiShen
  • 43
  • 1
  • 7

2 Answers2

0

1 I would make declaration of struct rather outside main than inside

2 Try changing char title[50] to char *title

#include <stdio.h>

struct Book {
    char *title;
    int year;
    float price;
};

int main() {

    int i;

    struct Book books[50];
    books[0].title = "Bullshit";
    books[0].year = 132;
    books[0].price = 146.9;

    books[1] = (struct Book) {"Money", 1344, 189.4
    };

    for (i = 0; i < 2; i++) {
        printf("Book Title is : %s\n", books[i].title);
        printf("Book Year is %d\n", books[i].year);
        printf("Book price is %3.2f\n", books[i].price);
        printf("\n\n");
    }
}

Why it didn't worked before?

In c arrays are not assignable by = operator.
You could do something like instead title[0] = 'B'; title[1] = 'u', etc....(or use strcpy which does it for you).

char *x is not really an array, it's just pointer to single char.
If we write x = "abc", we are telling the compiler: set x to 'a', next byte to 'b', next to 'c', and next to 0(not '0', just zero).

And when you do printf("%s",x), the printf function prints chars from the place in memory specified by x until it see 0 byte.

char *x = "abcd";

char *y = x;
while(*y != 0){   // this loop acts like printf("%s",x);
    printf("%c",*y);
    y++;
}

See also this and this question.

Or if you are using c++, not c, use std::string:

#include <cstdio>
#include <string>

struct Book {
    std::string title;
    int year;
    float price;

    Book(std::string t, int y, float p) {
        title = t;
        year = y;
        price = p;
    }
};

int main() {

    int i;

    Book books[50];
    books[0].title = "Bullshit";
    books[0].year = 132;
    books[0].price = 146.9;

    books[1] = Book(std::string("Money"), 1344, 189.4);

    for (i = 0; i < 2; i++) {
        printf("Book Title is : %s\n", books[i].title.c_str());
        printf("Book Year is %d\n", books[i].year);
        printf("Book price is %3.2f\n", books[i].price);
        printf("\n\n");
    }
}
J K
  • 632
  • 7
  • 24
  • 1
    If you are suggesting a change to `title` data structure, recommend `std::string`. – Thomas Matthews Mar 12 '18 at 15:31
  • Also, the OP could use `strncpy` rather than assignment or changing the array to a pointer. – Thomas Matthews Mar 12 '18 at 15:32
  • @ThomasMatthews yes, of course std::string, but this guy is writing in c, not c++(hmm... he didn't gave any information about it, but his code is more like c code than c++, that's why I didn't use std::string) – J K Mar 12 '18 at 15:38
  • @JK Well, if he would be writing in C, the question would be tagged as C, instead of C++. – Algirdas Preidžius Mar 12 '18 at 15:41
  • @AlgirdasPreidžius Original question hasn't got any tag about language, this tag has been added by edit. – J K Mar 12 '18 at 15:43
  • @JK Interesting.. Then, I would question the decision to replace C tag with C++ tag.. – Algirdas Preidžius Mar 12 '18 at 15:46
  • @AlgirdasPreidžius First, I've tagged it c++ because it was like c++ code. Then I noticed it's rather c code, but my second edit wasn't accepted. – J K Mar 12 '18 at 15:51
  • @JK Well, edit history shows you adding a C tag, and someone else replacing it with C++ tag. – Algirdas Preidžius Mar 12 '18 at 15:54
  • @AlgirdasPreidžius my question was made before that edit. And now i've also posted c++ code. – J K Mar 12 '18 at 15:58
  • Your second code does not produce desired result, because `books[i].title` is now a `std::string`, it does not print well with `printf` unless it is a `.c_str();` – Killzone Kid Mar 12 '18 at 16:17
  • sorry for late reply. But i am studying C instead of C++. Sorry if i do not tag it. But I tried d change char title[50] to char *title . It works. But i still dun know the concept. What is the difference? Can someone explain to me ? – TeoPeiShen Mar 13 '18 at 02:26
  • Thanks a lot. I hope you are the tutor in my university. – TeoPeiShen Mar 13 '18 at 12:48
  • Btw, why scanf("%s",title); works ?Why char title[9]="Bullshit"; works?Why char title[9]; title="Bullshit"; does not works? They looks like same. – TeoPeiShen Mar 13 '18 at 15:04
  • @TeoPeiShen You can write `char title[] = "Bullshit"`, and it means "create a string array that have length of 'Bullshit' string and insert it here." By writing `char title[9] = "Bullshit"` you are saying "create a string array that have length 9 and insert 'Bullshit' here." This is array initialization. "They looks like same." but they aren't. Second one(I mean code from your comment, not mine) is initialization, third one is assignment. – J K Mar 13 '18 at 17:51
0

this

books[0].title="Bullshit";

is not valid. title is defined as char[50]. Either do

strcpy(books[0].title, "BS");

This will copy the bytes of BS to title. Or do

 struct Book
    {
        char *title;
        int year;
        float price;
    };

...
  books[0].title = strdup("BS");

This sets title up as a pointer to a char string. strdup will allocate space for the string and copy BS to that space. You will have to free that allocated space.

Or - the best. Use std::string

 struct Book
    {
        std::string title;
        int year;
        float price;
    };
....
   books[0].title = "BS";

And as a final thought - life goes better with std::vector instead of raw arrays

pm100
  • 48,078
  • 23
  • 82
  • 145
  • "And as a final thought - life goes better with std::vector instead of raw arrays" - 100% agree ;) – J K Mar 12 '18 at 16:43
  • std::vector and std::string are c++ things. I see the tag has been changed to c. SO ignore those suggestions – pm100 Mar 12 '18 at 17:48