显示结构

问题描述 投票:1回答:2

该程序旨在根据用户的输入显示视频游戏库存。用户需要确定循环使用num_of_games运行多长时间。我们必须使用开关循环来确定类型。它编译但无法正确显示。

#include <stdio.h>
#include <string.h>
#define MAX 16

typedef enum genre_type{ action = 0, rpg = 1, simulation = 2, 
                        strategy = 3, sports = 4} genre_t;

typedef struct{
    char title[MAX];
    int num_sold;
    genre_t genre;
}game_s;
// suppose to use functions and enum list for determining the genre
void get_game_info(game_s *ptr);
void display_inventory(game_s game[], int num_of_games);


int
main(void){

    int i=0, num_of_games;
    int c_game=0;
    game_s game[num_of_games];

    printf("How many games are there in inventory? ");
    scanf("%d", &num_of_games);
    fflush(stdin);
    printf("\n");
    while(c_game < num_of_games){
        printf("\n");
        get_game_info(&game[c_game]);
        c_game++;
    }
    printf("\n");
    display_inventory(game, num_of_games);


    return(0);
}
void get_game_info(game_s *ptr)
{       
        int i, str_len, genre, num_sold;

        printf("Title of game <maximum of 15 characters>: ");
        gets(ptr->title);
        str_len = strlen(ptr->title);
            if(str_len >= 15){
                printf("Title will be truncated\n");
                ptr->title[MAX]= '\0';
            }
        printf("Number sold: ");
        scanf("%d", &ptr->num_sold);
        fflush(stdin);
        printf("Genre (0-action, 1-rpg, 2-simulation, 3-strategy, 4-sports): ");
        scanf("%d", &ptr->genre);
        fflush(stdin);
            if(ptr->genre>4){
                printf("Not a valid genre");
        fflush(stdin);  
}
}
void display_inventory(game_s game[], int num_of_games)
{   
    int i, genre;

    printf("Title\t\t\t\t\t\tQuantity Sold\t\t\t\t\t\tGenre");
    printf("\n=====\t\t\t\t\t\t=============\t\t\t\t\t\t=====\n");
    for(i=0; i < num_of_games; i++){
    switch(genre){
        case action: printf("Action"); break;
        case rpg: printf("RPG"); break;
        case simulation: printf("Simulation"); break;
        case strategy: printf("Strategy"); break;
        case sports: printf("Sports"); break;
        default: puts("Not a choice. Try again"); break;

我认为这是造成大部分问题的原因。我不知道我是否正在使用游戏[I] .title和其他人调用结构。我认为问题在于结构调用。如果我使用game_s [I] .title我得到“之前的预期表达”错误,如果我使用游戏[I] .title它不能正确打印

    printf("%s\t\t\t\t\t\t%d\t\t\t\t\t\t%s", game[i].title, game[i].num_sold, game[i].genre);
    printf("\n");
    }
    }
}
c struct
2个回答
0
投票

我认为问题是game_s game[num_of_games];,因为num_of_games不是发起人。

它应该是:

printf("How many games are there in inventory? ");
scanf("%d", &num_of_games);
game_s * game_s game = (game_s *) malloc(num_of_games * sizeof(game_s));

0
投票

你的努力是值得称道的。您提供代码并善意地尝试理解为什么事情不起作用,但不幸的是,您的代码充满了错误。通过尝试使用未初始化的num_of_games声明VLA,几乎可以立即调用未定义的行为。无论你从那时起你的代码中做了什么,它只不过是一个骰子滚动,无论你是否实际处理了某些东西或SegFaulted。

你在display_inventory缺乏输出(无论实际上是什么记忆)是由于你的printf声明在switch声明中的位置。当你从break switch,你不只是跳到default案件下面,你完全跳出switch。因此,即使代码的其余部分是正确的,您也永远不会产生输出。

fflush(stdin)是错误的,并且除了windoze外都会调用未定义的行为。它仅为世界其他地方的可搜索流定义 - 不要使用它。相反,您可以定义一个简单的函数来清空stdin并根据需要调用它。

编译时,始终在启用编译器警告的情况下进行编译,并且在没有警告的情况下干净地编译之前不要接受代码。要启用警告,请将-Wall -Wextra添加到gcc编译字符串中。 (添加-pedantic以获得其他几个警告)。对于VS(windoze上的cl.exe),添加/Wall。对于clang,添加-Weverything。阅读并理解每个警告。他们将识别任何问题,以及它们发生的确切线。您可以通过简单地聆听编译器告诉您的内容来学习编码,就像您可以从大多数教程中学到的那样。

您的代码中的错误数量太多,无法逐项列出并与每个点说话,所以我在下面列出了注释以解决错误。

#include <stdio.h>
#include <stdlib.h>     /* for EXIT_FAILURE */
#include <string.h>

#define MAX 16

typedef enum genre_type { 
    action = 0, 
    rpg = 1, 
    simulation = 2,
    strategy = 3, 
    sports = 4
} genre_t;

typedef struct {
    char title[MAX];
    int num_sold;
    genre_t genre;
} game_s;

// suppose to use functions and enum list for determining the genre
void get_game_info (game_s *ptr);
void display_inventory (game_s *game, int num_of_games);
void fflush_stdin();

int main (void) {

    int num_of_games,
        c_game = 0,
        scnfrtn;        /* scanf return - must always check EOF */

    printf ("How many games are there in inventory? ");
    for (;;) {  /* loop until valid input or EOF (user cancels) */
        if ((scnfrtn = scanf ("%d", &num_of_games)) == 1) {
            fflush_stdin(); /* manually empty stdin */
            break;
        }
        else if (scnfrtn == EOF) {  /* user cancels? */
            fprintf (stderr, "user canceled input.\n");
            exit (EXIT_FAILURE);
        }
        /* handle error */
        fprintf (stderr, "error: invalid input.\n");
        fflush_stdin();
    }
    putchar ('\n');             /* don't printf a single-char */

    /* declare VLA only AFTER num_of_games has a value */
    game_s game[num_of_games];
    memset (game, 0, sizeof game);  /* optional, zero VLA */

    while (c_game < num_of_games) {
        putchar ('\n');
        get_game_info (&game[c_game]);
        c_game++;
    }
    putchar ('\n');

    display_inventory (game, num_of_games);

    return 0;
}

void get_game_info (game_s *ptr)
{
    int scnfrtn;        /* scanf return - must always check EOF */
    size_t len = 0;     /* strlen return is size_t */

    printf ("Title of game <maximum of 15 characters>: ");
    fgets (ptr->title, MAX, stdin); /* NEVER, NEVER, NEVER use gets */
    len = strlen (ptr->title);
    if (len && ptr->title[len-1] == '\n')   /* check for trailing \n */
        ptr->title[--len] = '\0';    /* overwrite with nul-character */
    else    /* warn of truncation */
        fprintf (stderr, "error: title too long, truncated.\n");

    for (;;) {  /* loop until valid input or EOF (user cancels) */
        printf ("Number sold: ");
        if ((scnfrtn = scanf ("%d", &ptr->num_sold)) == 1) {
            fflush_stdin();
            break;
        }
        else if (scnfrtn == EOF) {
            fprintf (stderr, "user canceled input.\n");
            exit (EXIT_FAILURE);
        }
        fprintf (stderr, "error: invalid input.\n");
        fflush_stdin();
    }

    for (;;) {  /* loop until valid input or EOF (user cancels) */
        printf ("Genre (0-action, 1-rpg, 2-simulation, "
                "3-strategy, 4-sports): ");
        if ((scnfrtn = scanf ("%d", (int*)&ptr->genre)) == 1) {
            fflush_stdin();
            break;        
        }
        else if (scnfrtn == EOF) {
            fprintf (stderr, "user canceled input.\n");
            exit (EXIT_FAILURE);
        }
        else if (ptr->genre > 4)    /* additional check for genre */
            fprintf (stderr, "error: invalid genre.\n");
        else
            fprintf (stderr, "error: invalid input.\n");

        fflush_stdin();
    }
}

void display_inventory (game_s *game, int num_of_games)
{
    int i;

    printf ("%11s%-24s %-24s %s\n========================="
            "==============================================\n", 
            " ", "Title","Quantity Sold", "Genre");
    for (i = 0; i < num_of_games; i++) {
        switch (game[i].genre) {
            case action:
                printf ("%-11s", "Action");
                break;
            case rpg:
                printf ("%-11s", "RPG");
                break;
            case simulation:
                printf ("%-11s", "Simulation");
                break;
            case strategy:
                printf ("%-11s", "Strategy");
                break;
            case sports:
                printf ("%-11s", "Sports");
                break;
            default:
                puts ("Not a choice. Try again");
                break;
        }
        printf ("%-24s %-24u %d\n", game[i].title,
                game[i].num_sold, game[i].genre);
    }
}

void fflush_stdin()
{
    for (int c = getchar(); c != '\n' && c != EOF; c = getchar()) {}
}

(注意:使用printf最小字段和修饰符来控制间距而不是一堆tabs一起刷)

示例使用/输出

$ ./bin/gamegenre
How many games are there in inventory? 3


Title of game <maximum of 15 characters>: first title
Number sold: 12
Genre (0-action, 1-rpg, 2-simulation, 3-strategy, 4-sports): 2

Title of game <maximum of 15 characters>: second title
Number sold: 13
Genre (0-action, 1-rpg, 2-simulation, 3-strategy, 4-sports): 1

Title of game <maximum of 15 characters>: third title
Number sold: 14
Genre (0-action, 1-rpg, 2-simulation, 3-strategy, 4-sports): 3

           Title                    Quantity Sold            Genre
=======================================================================
Simulation first title              12                       2
RPG        second title             13                       1
Strategy   third title              14                       3

(注意:我不知道你的genre描述在哪里,所以它们只是在每行的开头输出)

仔细看看,如果您有其他问题,请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.