3
struct Person
{
    char name[40];
    int age;
};

int main() {
    struct Person people[15];
    struct Person *p_Person = people;
    for (int i = 0; i < 15; i++)
    {
        //strcpy(p_Person->name, ??? );
        p_Person->name[0] = 'a' + i;
        p_Person->name[1] = '\0';
        p_Person->age = i + 1;
        p_Person++;
    }
    return 0;
}

What I want to achieve is p_Person[0]->name = 'a', p_Person[1]->name = 'b' ...

The code above is working. I use p_Person->name[0] = 'a' + i; and terminate with a null character to initialize the char array.

What is the right code if I want to use strcpy to copy alphabet into p_Person->name?

5
  • 4
    Your posted code looks good, as it is. Although you can use strcpy for this, I would not regard this as an improvement. It will rather make your code more complicated. Commented Oct 10 at 5:01
  • 2
    Initialize the array or assign to the array? These are different things. Commented Oct 10 at 6:21
  • It seems a bit convoluted to introduce p_Person instead of just indexing into people (as people[i]). Or if you have some other reason to want p_Person then I would consider indexing using that (p_Person[i]), instead of updating the stored pointer value as the code presented does. Commented Oct 10 at 14:35
  • @panci matika, Tip: rather that code 15 twice, use self-documenting #define PERSON_N 15. Commented Oct 10 at 15:20
  • @panci matika It is entirely unclear what you are trying to do. Why is data member name declared with 40 characters? Why is there declared the array people with only 15 elements? Why is there the pointer p_Person used? Commented Oct 10 at 17:52

3 Answers 3

6

You might want this:

struct Person
{
    char name[40];
    int age;
};
int main() {
    struct Person people[15];
    struct Person *p_Person = people;
    char name[] = "a";
    for (int i = 0; i < 15; i++)
    {
        strcpy(p_Person->name, name);
        p_Person->age = i + 1;
        p_Person++;
        name[0]++;
    }
    return 0;
}

For non ASCII compatible code pages:

struct Person
{
    char name[40];
    int age;
};
int main() {
    struct Person people[15];
    char name[] = "a\0b\0c\0d\0e\0f\0g\0h\0i\0j\0k\0l\0m\0n\0o";
    for (int i = 0; i < 15; i++)
    {
        strcpy(people[i].name, &name[2 * i]);
        people[i].age = i + 1;
    }
    return 0;
}
Sign up to request clarification or add additional context in comments.

4 Comments

It may be worth noting that the ISO C standard does not require that the character codes for a to z are contiguous. This code will work on ASCII-based character sets (i.e. most commonly used character sets), but will not work on for example EBCDIC.
The answer is based on the OP' code 'a' + i.
3CEZVQ, Minor, "For non ASCII compatible code pages:" sounds like the code is for non ASCII only when it is for ASCII and non-ASCII - a highly portable effort even though ASCII is the case 99.99...% of the time.
For the second example, name[2 * i] should be &name[2 * i] in the strcpy call. You might as well use static const name[]. Also, it may be more readable with a 2D array, static const char name[][2] = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o" }; with name[i] in the strcpy call.
3

Initialize char array with alphabet

Initialize has a particular meaning in C. To initialize means to define a value at object definition/creation time.

// Example
int i = 123;

What OP's code is doing is assignment after definition. @Lundin


To initialize consider:

struct Person people[15] = {
  { "a", 1}, { "b", 2}, { "c", 3}, { "d", 4}, { "e", 5}, 
  { "f", 6}, { "g", 7}, { "h", 8}, { "i", 9}, { "j", 10}, 
  { "k", 11}, { "l", 12}, { "m", 13}, { "n", 14}, { "o", 15},
}; 

This will also fill the remainder of the .name[] members with null characters.

strcpy(), nor other functions, cannot be used to initialize (in the C sense of the word).


What is preferable depends on larger programming needs.


@Eric Postpischil offers a different take on initialize.

C 2024 defines “initialized” as “set to their initial values” in passing in 5.2.2.1: “All objects with static storage duration shall be initialized (set to their initial values) before program startup” (italics in original). Note it does not say that the setting has to be at definition or creation time. In 6.3.3.1, we see that initialization may be done by assignment: “… that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use)…”

Comments

3

I would suggest the following, which doesn't rely on ASCII being used, as tempting as it is to take that for granted, and also avoids magic numbers, and the silly p_Person pointer variable.

The only potential problem here occurs if NUM_PEOPLE exceeds 26.

#include <stdlib.h>

#define NAME_LENGTH 40
#define NUM_PEOPLE 15

struct Person {
    char name[NAME_LENGTH];
    int age;
};

int main(void) {
    const char *alphabet = "abcdefghijklmnopqrstuvwxyz";

    struct Person people[NUM_PEOPLE];

    for (size_t i = 0; i < NUM_PEOPLE; i++) {
        people[i].name[0] = alphabet[i];
        people[i].name[1] = '\0';
        people[i].age = i + 1;
    }
}

You might also use a compound literal.

    for (size_t i = 0; i < NUM_PEOPLE; i++) {
          people[i] = (struct Person){ 
              .name={alphabet[i], '\0'}, 
              .age=i + 1 
          };
    }

1 Comment

You can remove the redundant , '\0' from the designated field initializer for .name.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.