C Void结局问题

C Void ending issue

我正在尝试编写一个简单的停车安排代码,我想按1000辆车、颜色、车牌和型号对容量进行排序

#include <stdio.h>
#include <stdlib.h>
void NewCar()
{
    char model[1000][20];
    char color [1000][20];
    char number[1000][20];
    int x = 1;
        printf("\nModel: ");
        scanf("%s",model[x]);
        printf("Color: ");
        scanf("%s",color[x]);
        printf("Number: ");
        scanf("%s",number[x]);
}
void CarList()
{
    int x;
    char model[1000][20];
    char color [1000][20];
    char number[1000][20];
    for (x ; x >= 1 ; x--)
    {
        printf("\n%d. Car: %s %s %s",x,number[x],model[x],color[x]);
    }
}
int main()
{
    char model[1000][20];
    char color [1000][20];
    char number[1000][20];
    char menu;
    int x = 1;
    flag:
    printf("New Car(N)\nCar List(L)\n");
    scanf("%s",&menu);
    if (menu == "n" || menu == "N")
    {
        NewCar();
        goto flag;
    }
    if (menu == "l" || menu == "L")
    {
        CarList();
        goto flag;
    }
}

当我不使用 void 时,代码可以工作,但我必须使用 void

我想要的输出示例;

 1. Car Red Jeep FGX9425
 2. Car Yellow Truck OKT2637
 3. Car Green Sedan ADG4567
 ....

这是我的热门评论。

从不 使用 goto。使用(例如)while 循环。

menuscanf [可能] 会溢出。

正如其他人所提到的,存在一些错误。

我已经用你的旧代码和一些新代码重构了你的代码。这仍然需要更多的错误检查,并且可以泛化更多一点,但是,我已经测试了它的基本功能:

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

// description of a car
struct car {
    char model[20];
    char color[20];
    char number[20];
};

int
NewCar(struct car *cars,int carcount)
{
    struct car *car = &cars[carcount];

    printf("\nModel: ");
    scanf("%s", car->model);

    printf("\nColor: ");
    scanf("%s", car->color);

    printf("\nNumber: ");
    scanf("%s", car->number);

    ++carcount;

    return carcount;
}

void
CarList(struct car *cars,int carcount)
{
    struct car *car;
    int caridx;

    for (caridx = 0;  caridx < carcount;  ++caridx) {
        car = &cars[caridx];
        printf("%d. Car: %s %s %s\n",
            caridx + 1, car->number, car->model, car->color);
    }
}

int
main(int argc,char **argv)
{
#if 1
    int carcount = 0;
    struct car carlist[1000];
#endif
#if 0
    char menu;
    int x = 1;
#else
    char menu[20];
#endif

    // force out prompts
    setbuf(stdout,NULL);

    while (1) {
        printf("New Car(N)\nCar List(L)\n");
#if 0
        scanf("%s", &menu);
#else
        scanf(" %s", menu);
#endif

        // stop program
        if ((menu[0] == 'q') || (menu[0] == 'Q'))
            break;

        switch (menu[0]) {
        case 'n':
        case 'N':
            carcount = NewCar(carlist,carcount);
            break;

        case 'l':
        case 'L':
            CarList(carlist,carcount);
            break;
        }
    }

    return 0;
}

更新:

As you said, there are a few minor errors, it's not a problem for me, but I can write errors if you want to know and fix them.(if you write the plate with a space between it, the code repeats the "new car car list" command many times)

好的,我制作了一个增强版本,用使用 fgets 的函数 askfor 替换了 scanf。后者将防止 [意外] 缓冲区溢出。而且,混合使用 scanf fgets 可能会有问题。就个人而言,我总是 "roll my own" 使用 fgets 因为它可以提供更精细的粒度控制 [如果与包装函数一起使用,例如此处提供的 askfor]

编辑: Per chux,我用使用 strchr:

的更安全版本替换了用于删除换行符的 strlen
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define STRMAX      20

// description of a car
struct car {
    char model[STRMAX];
    char color[STRMAX];
    char number[STRMAX];
};

// askfor -- ask user for something
void
askfor(const char *tag,char *ptr)
{

    printf("Enter %s: ",tag);
    fflush(stdout);

    fgets(ptr,STRMAX,stdin);

    // point to last char in buffer
    // remove newline
#if 0
    ptr += strlen(ptr);
    --ptr;
    if (*ptr == '\n')
        *ptr = 0;
#else
    // remove trailing newline [if it exists]
    ptr = strchr(ptr,'\n');
    if (ptr != NULL)
        *ptr = 0;
#endif
}

int
NewCar(struct car *cars,int carcount)
{
    struct car *car = &cars[carcount];

    askfor("Model",car->model);
    askfor("Color",car->color);
    askfor("Number",car->number);

    ++carcount;

    return carcount;
}

void
CarList(struct car *cars,int carcount)
{
    struct car *car;
    int caridx;

    for (caridx = 0;  caridx < carcount;  ++caridx) {
        car = &cars[caridx];
        printf("%d. Car: %s %s %s\n",
            caridx + 1, car->number, car->model, car->color);
    }
}

int
main(int argc,char **argv)
{
    int carcount = 0;
    struct car carlist[1000];
    char menu[STRMAX];

    // force out prompts
    setbuf(stdout,NULL);

    while (1) {
        askfor("\nNew Car(N)\nCar List(L)",menu);

        // stop program
        if ((menu[0] == 'q') || (menu[0] == 'Q'))
            break;

        switch (menu[0]) {
        case 'n':
        case 'N':
            carcount = NewCar(carlist,carcount);
            break;

        case 'l':
        case 'L':
            CarList(carlist,carcount);
            break;
        }
    }

    return 0;
}

更新#2:

Thank you for your bug fix, but as I said in my question, I have to do the "New car" feature using void. You did it with int, can you do it with void?

好的。当你说 "using void" 时,我 [或其他一些人] 并不完全清楚你的意思。有足够多的错误,它们掩盖了其他一些考虑因素。

所以,我不得不假设 "using void" 意味着函数 return void.

您的原始函数定义为 void NewCar()void CarList()。那些无法按原样完成工作,因此必须对其进行更改。

如果您有类似的标准,更好的表达方式是:

I must create two functions, with the following function signatures ...

无论如何,这是更新后的代码:

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

#define STRMAX      20

// description of a car
struct car {
    char model[STRMAX];
    char color[STRMAX];
    char number[STRMAX];
};

// askfor -- ask user for something
void
askfor(const char *tag,char *ptr)
{

    printf("Enter %s: ",tag);
    fflush(stdout);

    fgets(ptr,STRMAX,stdin);

    // remove trailing newline [if it exists]
    ptr = strchr(ptr,'\n');
    if (ptr != NULL)
        *ptr = 0;
}

void
NewCar(struct car *cars,int *countptr)
{
    int carcount = *countptr;
    struct car *car = &cars[carcount];

    askfor("Model",car->model);
    askfor("Color",car->color);
    askfor("Number",car->number);

    carcount += 1;
    *countptr = carcount;
}

void
CarList(struct car *cars,int carcount)
{
    struct car *car;
    int caridx;

    for (caridx = 0;  caridx < carcount;  ++caridx) {
        car = &cars[caridx];
        printf("%d. Car: %s %s %s\n",
            caridx + 1, car->number, car->model, car->color);
    }
}

int
main(int argc,char **argv)
{
    int carcount = 0;
    struct car carlist[1000];
    char menu[STRMAX];

    // force out prompts
    setbuf(stdout,NULL);

    while (1) {
        askfor("\nNew Car(N)\nCar List(L)",menu);

        // stop program
        if ((menu[0] == 'q') || (menu[0] == 'Q'))
            break;

        switch (menu[0]) {
        case 'n':
        case 'N':
#if 0
            carcount = NewCar(carlist,carcount);
#else
            NewCar(carlist,&carcount);
#endif
            break;

        case 'l':
        case 'L':
            CarList(carlist,carcount);
            break;
        }
    }

    return 0;
}

但是,鉴于您的原始函数,签名 可能是:void NewCar(void)void CarList(void) 并且汽车列表变量必须是全局范围。

这将是一种不太灵活和可取的做事方式,但这里有一个仅对列表使用全局变量的版本:

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

#define STRMAX      20

// description of a car
struct car {
    char model[STRMAX];
    char color[STRMAX];
    char number[STRMAX];
};

#if 1
int carcount = 0;
struct car carlist[1000];
#endif

// askfor -- ask user for something
void
askfor(const char *tag,char *ptr)
{

    printf("Enter %s: ",tag);
    fflush(stdout);

    fgets(ptr,STRMAX,stdin);

    // remove trailing newline [if it exists]
    ptr = strchr(ptr,'\n');
    if (ptr != NULL)
        *ptr = 0;
}

void
NewCar(void)
{
    struct car *car = &carlist[carcount];

    askfor("Model",car->model);
    askfor("Color",car->color);
    askfor("Number",car->number);

    carcount += 1;
}

void
CarList(void)
{
    struct car *car;
    int caridx;

    for (caridx = 0;  caridx < carcount;  ++caridx) {
        car = &carlist[caridx];
        printf("%d. Car: %s %s %s\n",
            caridx + 1, car->number, car->model, car->color);
    }
}

int
main(int argc,char **argv)
{
#if 0
    int carcount = 0;
    struct car carlist[1000];
#endif
    char menu[STRMAX];

    // force out prompts
    setbuf(stdout,NULL);

    while (1) {
        askfor("\nNew Car(N)\nCar List(L)",menu);

        // stop program
        if ((menu[0] == 'q') || (menu[0] == 'Q'))
            break;

        switch (menu[0]) {
        case 'n':
        case 'N':
#if 0
            carcount = NewCar(carlist,carcount);
#else
            NewCar();
#endif
            break;

        case 'l':
        case 'L':
#if 0
            CarList(carlist,carcount);
#else
            CarList();
#endif
            break;
        }
    }

    return 0;
}