用于停车模拟的C程序不提供输出

时间:2017-08-23 05:49:46

标签: c malloc c-strings

我想写一个C程序,其中我有一个10个字符串的数组,其中每个字符串表示停在现场i的车牌号。随机挑选一个点,如果它是空的,则生成随机车牌号并将其分配给该点,如果它被占用,则该点空出并删除车牌号。但是,程序进入无限循环,这是我想要的,但它不打印我为调试程序而编写的任何语句。代码如下:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <stdint.h>

char * generateLicense()
{
    srand((unsigned)time(NULL));
    char const *code[] = {"AN","AP","AR","AS","BR","CG","CH","DD","DL","DN","GA","GJ","HR","HP","JH","JK","KA","KL","LD","MH","ML","MP","MN","MZ","NL","OD","PB","PY","RJ","SK","TN","TR","TS","UK","UP","WB"};
    char const *alphabets[] = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
    char const *numbers[] = {"0","1","2","3","4","5","6","7","8","9"};  
    char *licensePlate = (char *)malloc(100*sizeof(char));
    strcpy(licensePlate,code[rand()%36]);
    strcat(licensePlate,"-");
    strcat(licensePlate,numbers[rand()%10]);
    strcat(licensePlate,numbers[rand()%10]);
    strcat(licensePlate,"-");
    strcat(licensePlate,alphabets[rand()%26]);
    strcat(licensePlate,alphabets[rand()%26]);
    strcat(licensePlate,"-");
    strcat(licensePlate,numbers[rand()%10]);
    strcat(licensePlate,numbers[rand()%10]);
    strcat(licensePlate,numbers[rand()%10]);
    strcat(licensePlate,numbers[rand()%10]);
    return licensePlate;    
}

int main()
{
    char *messagebody = (char *)malloc(100*sizeof(char));
    char *licensePlate = (char *)malloc(100*sizeof(char));
    char *currentSpot = (char *)malloc(10*sizeof(char));
    char *by = ", by: ";
    char *client = "From client 1, ";
    char *spots[] = {"00-00-00-0000","00-00-00-0000","00-00-00-0000","00-00-00-0000","00-00-00-0000","00-00-00-0000","00-00-00-0000","00-00-00-0000","00-00-00-0000","00-00-00-0000"};
    int spot;
    printf("variables declared\n");
    srand((unsigned)time(NULL));
    while(1)
    {
        printf("in while loop\n");
        //messagebody = "";
        //licensePlate = "";
        spot = rand()%10;
        //currentSpot = "";
        sprintf(currentSpot, "%d", spot);
        printf("%s",currentSpot);
        strcpy(messagebody,client);
        printf("%s",messagebody);
        if(spots[spot] == "00-00-00-0000")
        {
            printf("%s",messagebody);
            strcpy(licensePlate, generateLicense());
            printf("%s",licensePlate);
            strcpy(spots[spot], licensePlate);
            strcat(messagebody,"spot occupied: ");
            printf("%s",messagebody);
            strcat(messagebody,currentSpot);
            printf("%s",messagebody);
            strcat(messagebody,by);
            printf("%s",messagebody);
            strcat(messagebody,licensePlate);
            printf("%s",messagebody);
        }
        else
        {
            printf("%s",messagebody);
            strcpy(licensePlate, spots[spot]);
            strcpy(spots[spot],"00-00-00-0000");
            strcat(messagebody,"spot vacated: ");
            printf("%s",messagebody);
            strcat(messagebody,currentSpot);
            printf("%s",messagebody);
            strcat(messagebody,by);
            printf("%s",messagebody);
            strcat(messagebody,licensePlate);
            printf("%s",messagebody);
        }
        printf("%s",messagebody);
        sleep(5);
    }
    return 0;
}

我已经包含了我为调试程序而编写的语句。我在这里做错了什么?

1 个答案:

答案 0 :(得分:4)

您的程序存在访问冲突:spots是一个包含十个字符串文字的数组:

char *spots[] = {
    "00-00-00-0000",
    "00-00-00-0000",
    "00-00-00-0000",
    ...
};

这些文字是不可变的,试图改变它们是一种恐怖。

相反,定义一个包含10个字符数组的数组,可以容纳您的号牌。您需要为模式2-2-2-4添加空间,并为null终止符添加一个char:

char spots[10][14] = {""};

现在spots是10个空字符串。长度13.您可以测试是否已经覆盖了它们:

if (*spots[spot] == '\0') ... // string is empty

您的代码存在更多问题:

  • 对于如此小的程序来说,动态内存分配实际上是不必要的并且使其复杂化。您有10个带13个字母牌照的插槽,可以在自动存储器中轻松创建。
  • 不要为牌照分配内存,然后strcpy。通过将14-char缓冲区传递给填充它的函数来直接创建牌照。
  • 冗长的strcat序列非常笨拙。考虑使用snprintf,它将在几乎一次创建一个牌照。

这里是您的问题的简明实施,仅限于30次停车行动:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

void make_license(char str[])
{
    static const char *code[] = {
        "AN", "AP", "AR", "AS", "BR", "CG", "CH", "DD", "DL",
        "DN", "GA", "GJ", "HR", "HP", "JH", "JK", "KA", "KL",
        "LD", "MH", "ML", "MP", "MN", "MZ", "NL", "OD", "PB",
        "PY", "RJ", "SK", "TN", "TR", "TS", "UK", "UP", "WB"
    };

    snprintf(str, 14, "%s-%02d-%c%c-%04d",
        code[rand() % 36], rand() % 100, 
        'A' + rand() % 26, 'A' + rand() % 26,
        rand() % 10000);    
}

int main()
{
    char spots[10][14] = {""};
    int n = 30;

    srand(time(NULL));

    while (n--) {
        int spot = rand() % 10;

        if (*spots[spot]) {
            printf("Car %s leaves spot %d.\n", spots[spot], spot + 1);

            *spots[spot] = '\0';            // remove licence plate
        } else {
            make_license(spots[spot]);      // create licence plate

            printf("Car %s arrives at spot %d.\n", spots[spot], spot + 1);
        }
    }

    puts("");
    puts("Final arrangement");

    for (n = 0; n < 10; n++) {
        printf("%4d %s\n", n + 1, spots[n]);
    }

    return 0;
}

如果您想使用动态分配(可能是分配的要求),您应该将许可证板指向字符串。将它们初始化为NULL,如果您从列表中删除它们,请将它们释放,并确保在您完成后释放任何剩余的字符串:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

char *make_license(void)
{
    static const char *code[] = {
        "AN", "AP", "AR", "AS", "BR", "CG", "CH", "DD", "DL",
        "DN", "GA", "GJ", "HR", "HP", "JH", "JK", "KA", "KL",
        "LD", "MH", "ML", "MP", "MN", "MZ", "NL", "OD", "PB",
        "PY", "RJ", "SK", "TN", "TR", "TS", "UK", "UP", "WB"
    };

    char *str = malloc(14);

    snprintf(str, 14, "%s-%02d-%c%c-%04d",
        code[rand() % 36], rand() % 100, 
        'A' + rand() % 26, 'A' + rand() % 26,
        rand() % 10000);

    return str; 
}

int main()
{
    char *spots[10] = {NULL};
    int n = 30;

    srand(time(NULL));

    while (n--) {
        int spot = rand() % 10;

        if (spots[spot]) {
            printf("Car %s leaves spot %d.\n", spots[spot], spot + 1);

            free(spots[spot]);
            spots[spot] = NULL;             // remove licence plate
        } else {
            spots[spot] = make_license();   // create licence plate

            printf("Car %s arrives at spot %d.\n", spots[spot], spot + 1);
        }
    }

    puts("");
    puts("Final arrangement");

    for (n = 0; n < 10; n++) {
        printf("%4d %s\n", n + 1, spots[n] ? spots[n] : "--");
        free(spots[n]);
    }

    return 0;
}

但你应该明确决定采取哪种方法。你的程序介于两者之间:它分配内存,然后在数据周围尝试strcpy,就像使用自动内存缓冲区一样。