我想写一个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;
}
我已经包含了我为调试程序而编写的语句。我在这里做错了什么?
答案 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
您的代码存在更多问题:
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
,就像使用自动内存缓冲区一样。