C Пустая конечная проблема - PullRequest
0 голосов
/ 13 апреля 2020

Я пытаюсь написать простой код организации парковки, хочу отсортировать вместимость по 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;
    }
}

Code Output

когда я не использую void, код работает, но я должен использовать void

Пример вывода, который я хочу;

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

1 Ответ

2 голосов
/ 13 апреля 2020

Это предварено моими главными комментариями.

Никогда использовать goto. Используйте (например) a while l oop.

Ваш scanf для menu [вероятно] переполнится.

Как уже упоминалось, ряд ошибок.

Я реорганизовал ваш код с вашим старым кодом и новым кодом. Это все еще требует дополнительной проверки ошибок и может быть обобщено немного больше, но я проверил ее на базовую c функциональность:

#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;
}

ОБНОВЛЕНИЕ:

Как вы сказали, есть несколько мелких ошибок, для меня это не проблема, но я могу написать ошибки, если вы хотите знать и исправить их (если вы пишете табличку с пробелом между ними) код повторяет команду «список новых автомобилей» много раз)

Хорошо, я создал расширенную версию, которая заменяет scanf на функцию askfor, которая использует fgets , Последнее предотвратит [случайное] переполнение буфера. И смешивание scanf и fgets может быть проблематичным c. Лично я всегда «катлюсь сам», используя fgets, поскольку это может обеспечить более точный контроль зерна [если используется с функциями оболочки, такими как askfor, предоставленными здесь]

Редактировать: Для чукса я заменил strlen для удаления новой строки на более безопасную версию, которая использует strchr:

#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;
}

UPDATE # 2:

Спасибо за исправление ошибки, но, как я уже сказал в своем вопросе, я должен использовать функцию "Новый автомобиль", используя void. Вы сделали это с int, вы можете сделать это с void?

Хорошо. Когда вы сказали «используя пустоту», то, что вы имели в виду, было не совсем понятно для меня [или некоторых других]. Было достаточно ошибок, которые затмили некоторые другие соображения.

Итак, я должен предположить, что «использование void» означает, что функции возвращают void.

Ваши исходные функции были определены как void NewCar() и void CarList(). Те, кто не мог сделать работу как есть, поэтому их пришлось изменить.

Если у вас есть похожие критерии, лучший способ сформулировать это так:

Я должен создать две функции со следующими сигнатурами функций ...

В любом случае, вот обновленный код:

#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) и переменные списка автомобилей должны быть global scope.

Это был бы менее гибкий и желательный способ делать вещи, но вот версия, которая использует только глобальные переменные для списков:

#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;
}
...