0

What is the best way for one to iterate through a mutable array of strings? For example:

struct Book{
    char chapter_names[20][50];
    int chapters;
    ...}

int main(){
    struct Book Redwall;
    strcpy(*chapter_names, "The Wall");
    strcpy(*(++chapter_names), "The Grove");

    printf("Chapter 1: %s", chapter_names[0]);
    printf("Chapter 2: %s", chapter_names[1]);

    return 0;
}

I would like the output of this to be:

Chapter 1: The Wall
Chapter 2: The Grove

This code resulted in

error: lvalue is required as increment operand
David
  • 89
  • 9
  • What happened when you tried to compile this code? – Chris Turner Jan 20 '17 at 16:50
  • Edited it into the question – David Jan 20 '17 at 16:53
  • `chapter_names` is an array. You can't increment an array... – Eugene Sh. Jan 20 '17 at 16:54
  • You can't increment an array, whether that's a plain array or a structure member. Use indexing — it isn't painful and it is easy to read and hard(er) to get wrong. – Jonathan Leffler Jan 20 '17 at 16:54
  • Was taught that the name of the array is equal to the address of the array. aka `array == &array == &array[0]` – David Jan 20 '17 at 16:55
  • @David Which is not implying you can *modify* it. – Eugene Sh. Jan 20 '17 at 16:57
  • Even if you could modify it, you wouldn't know where the array started any more. – Chris Turner Jan 20 '17 at 16:58
  • 1
    Sorta, but arrays aren't pointers. `array` converts to `&array[0]` and they're the same type, but `&array` is a different type (albeit with the same initial value). Given `int array[10];`, then `&array` is an `int (*)[10]` — a pointer to an array of 10 integers; adding 1 to that (i.e. `&array + 1`) leaves you accessing out of array bounds, quite different from `array + 1` which is in bounds. Arrays are not pointers. And you can't increment array names. – Jonathan Leffler Jan 20 '17 at 16:59

2 Answers2

1

You can't use increment operator like that on an array within a struct. You are probably looking for code like below:

struct Book{
    char chapter_names[20][50];
    int chapters;
    };

    int main(){
        struct Book Redwall;
        strcpy(*(Redwall.chapter_names), "The Wall");
        strcpy(*(Redwall.chapter_names+1), "The Grove");

        printf("Chapter 1: %s\n", Redwall.chapter_names[0]);
        printf("Chapter 2: %s\n", Redwall.chapter_names[1]);

        return 0;
    }
16tons
  • 675
  • 5
  • 14
  • Why not use `Redwall.chapter_names[0]` etc in the `strcpy()` lines too? It would be a lot simpler to understand — and no slower. – Jonathan Leffler Jan 20 '17 at 17:00
  • Precisely. Since OP seemed somewhat new to this, I just wanted for him to get the idea of `(a[1] == (a+1))`. So I kept `chapter_names+1` in assignment and `chapter_names[1]` in print. – 16tons Jan 20 '17 at 17:04
  • 2
    Surely better to teach them good habits now, than encourage their existing bad ones. – Chris Turner Jan 20 '17 at 17:05
  • So `a++` literally means `a+=1` thus moving `a` out of bounds. What I want to do is pass `a+1`. Got it – David Jan 20 '17 at 17:07
0

Since you've got an int to track how many chapter names you've got, you should probably use it.

Redwall.chapters = 0; // Make sure it's initialised first
strcpy(Redwall.chapter_names[Redwall.chapters++], "The Wall");
strcpy(Redwall.chapter_names[Redwall.chapters++], "The Grove");

And then you can use a for loop to cycle through each of them.

for(i=0;i<Redwall.chapters;i++) {
     printf("Chapter %d: %s", i+1, Redwall.chapter_names[i]);
} 
Chris Turner
  • 8,082
  • 1
  • 14
  • 18