使用有限的字符串自动填充数组元素

时间:2016-03-21 17:43:27

标签: c arrays struct

假设您在船上有12名乘客。他们每个人都不同。 这12名乘客分为以下几类:

  • 年龄
  • 性别

每个类别都有2个不同的选项:

  • 课程是"第一个"或"秒"

  • 年龄是成年人"或者"孩子"

  • 性别是"男性"或"女性"

我决定创建一个类型为struct的新数据类型,名为" Passenger"。正如您将在下面的代码中看到的,它有三个成员:class,age,gender。

然后我创建了这个新创建的数据类型(Passenger)的变量(allPassengers)。

但现在,我如何填写Passenger类型的数组" allPassengers"关于乘客的所有12种不同信息组合?

E.g。我手动创建了前三个组合:

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

    typedef struct {
        char class[7];
        char age[6];
        char gender[7];
    }
Passenger;


/* This is where all the information about passengers will be stored, global variable,
there are 9 combinations of passengers (allocated array elements for the variable), last one is reserved for the null character \0 */
Passenger allPassengers[10];


int main() {

    // First combination
    strcpy(allPassengers[0].class, "first");
    strcpy(allPassengers[0].age, "adult");
    strcpy(allPassengers[0].gender, "male");


    // Second combination
    strcpy(allPassengers[1].class, "second");
    strcpy(allPassengers[1].age, "adult");
    strcpy(allPassengers[1].gender, "male");


    // Third combination
    strcpy(allPassengers[2].class, "first");
    strcpy(allPassengers[2].age, "child");
    strcpy(allPassengers[2].gender, "male");

    // ... etc

    return 0;
}

Here's相同的代码(复制粘贴友好)。

我知道它很容易用数字填充数组(for循环)。但我不知道如何填写前两个allPassengers[0]allPassengers[1]以及必要的信息。我想我会写一个复杂的&#34; if语句&#34;在for循环中,例如检查以前的allPassengers的类,例如如果有超过2个匹配,则分配类&#34;秒&#34;。

或切换案例......不知道。如果我必须填写更难的组合怎么办。

我如何只允许变量的有限字符串?例如上课可以采取&#34;第一&#34;或&#34;秒&#34;?

任何线索?

4 个答案:

答案 0 :(得分:0)

如果您的数据严格限制在您所说的特定值,我建议您创建枚举类型。

示例:

enum ClassEnum{
FIRST,
SECOND
};

enum AgeEnum{
   ADULT,
   CHILD
};

enum GenderEnum{
   MALE,
   FEMALE
};

typedef struct {
        ClassEnum class;
        AgeEnum age;
        GenderEnum gender;
    }
Passenger; 

它将简化您要执行的操作,因为您不再需要操作字符串。

为了用每种组合填充数组,你没有其他选择来编写将遍历所有组合的函数。

答案 1 :(得分:0)

我建议你定义一个函数,它接受一个乘客结构的指针和一组用于初始化结构的属性值。例如:

void init_passenger(Passenger *passenger, const char *class,
    const char *age, const char *gender) {
    strcpy(passenger->class, class);
    /* ... */
}

我也会避免magic numbers并定义宏

#define CLASS_MAX_LEN 7
#define AGE_MAX_LEN 6
#define GENDER_MAX_LEN 7

使结构定义变为

typedef struct {
    char class[MAX_CLASS_LEN];
    char age[MAX_AGE_LEN];
    char gender[MAX_GENDER_LEN];
} Passenger;

如果空间不是问题,您可以拥有一个宏

#define MAX_LEN 7

要填写乘客数组,只需调用函数init_passenger(allPassengers[i], "firstm "child", "male")以获取i的适当值(以及相应的属性值)。

您可以通过嵌套三个循环遍历所有可能的值,每个循环对应一个可能的属性值数组(如单独答案中所示)。

P.S。我想你正在使用众所周知的Titanic dataset。那是准确的吗?

答案 2 :(得分:0)

我建议使用空终止的字符串数组,它们在C中是以空字符结尾的字符数组。

char **classes = { "first", "second", NULL };
char **ages = { "child", "adult", NULL };
char **gender = { "female", "male", NULL };

for( char **class = classes; class; class++ ) {
    for( char **age = ages; age; age++ ) {
        for( char **gender = genders; gender; gender++ ) {

请注意,++运算符在char **变量上运行而不在char *变量上运行,因此您将通过列表中的字符串递增而不是一个特定字符串中的字符。空终止允许一个非常简单的第二项,仅用于循环变量本身的for循环。这种方法是可以推广的,因为您可以简单地将新的类别值添加到字符串列表中,逻辑基本相同。 (虽然当您添加更多类别值时,随着组合数量的增加,您需要预先分配更多空间)

答案 3 :(得分:0)

每位乘客都有三个属性,每个属性都有两个可能的值,所以有  2 3 =总共8种可能性。要填充数组,我们可以使用binary number的概念。

在下面的代码中,p用作allPassengers数组的索引,同时,p的二进制表示用于选择字符串。 p的最高有效位确定gender,中间位确定age,最低有效位确定class

Passenger allPassengers[8];

int main( void )
{
    for ( int p = 0; p < 8; p++ )
    {
        char *gender = (p & 4) ? "female" : "male";
        char *age    = (p & 2) ? "child"  : "adult";
        char *class  = (p & 1) ? "second" : "first";

        strcpy( allPassengers[p].gender, gender );
        strcpy( allPassengers[p].age, age );
        strcpy( allPassengers[p].class, class );
    }

    for ( int p = 0; p < 8; p++ )
        printf( "%-6s %s %-6s\n", allPassengers[p].class, allPassengers[p].age, allPassengers[p].gender );
}