打印一组结构,C

时间:2018-03-02 19:25:59

标签: c arrays struct

我想打印我的结构数组但是我一直在分段错误, 我究竟做错了什么?我首先使用另一个函数来读入数据。然后我想能够查看我刚输入的内容。

#include <stdio.h>

#define max 100
#define min 30
struct vara{
    char namn[min];
    int saldo;
    int nummer;
};
struct vara varor[max];

int addvara(struct vara varor[], int length)
{
    int s, n = 1;
    //char nm;
    printf("Vill du scanna in vara? 1 för ja. 0 för att återgå till menyn\n");
    scanf("%d", &n);
    while(n != 0)
    {
        for(int i=0; i<length; i++)
        {
            printf("Namm, saldo, varunummer\n");
            scanf("%s", varor[i].namn);
            scanf("%d", &varor[i].saldo);
            scanf("%d", &varor[i].nummer);
            //struct vara invara = {"%s, %d, %d", nm, s, n};
            //varor[length] = invara;
            i=length;
            length++;
            printf("Vill du scanna in vara? 1 för ja. 0 för att återgå till menyn\n");
            scanf("%d", &n);
        }

    }
    return length;
}

void view(struct vara varor[], int length)
{
    printf("Varunummer \t\t Namn \t\t Varunummer\n");
    for(int i=0; i<length; i++)
    {
        printf("%s \t\t %d \t\t %d", varor[i].namn, varor[i].saldo, varor[i].nummer);
    }
}

1 个答案:

答案 0 :(得分:3)

我认为问题的根源是你的addvara函数,你的循环没有意义。

使用i=length;覆盖正在运行的索引,然后执行 length++;。如果用户希望继续,则退出for循环并输入它 再次,根据用户输入值的次数,你是 最终访问varor越界,这是未定义的行为 并且这是一个分段错误。

我会像这样重写addvara函数:

// helper function to clean stdin
void clean_stdin()
{
    int c;
    while((c = getchar()) != '\n' && c != EOF);
}

// helper function to read in a loop until you get the value
// return 1 on success, 0 on failure, cannot continue reading
int read_from_stdin(const char *format, void *ptr, const char *prompt)
{
    int err;
    do {
        if(prompt)
        {
            printf("%s", prompt);
            fflush(stdout);
        }

        err = scanf(format, ptr);

        if(err == EOF)
            return 0;

        if(err != 1)
        {
            printf("Invalid value, try again\n");
            clean_stdin();
        }

    } while(err != 1);

    return 1;
}

int addvara(struct vara varor[], int length)
{

    if(varor == NULL)
        return -1; // error value

    if(length < 0)
        return -1;

    // helper to creata a format for scanf
    // %29[^\n]s, the number depends on sizeof varor[0].namn
    char strfmt[100];
    sprintf(strfmt, "%%%zu[^\n]s", sizeof(varor[0].namn) - 1);

    int i;
    for(i = 0; i < length; ++i)
    {
        int ask;

        if(read_from_stdin("%d", &ask, "Vill du scanna in vara? 1 för ja. 0 för att återgå till menyn\n") == 0)
        {
            fprintf(stderr, "cannot continue reading\n");
            return i; // number of values added so far
        }

        if(ask == 0)
            return i; // the number of values added

        // otherwise scanf might complain about leftovers in the input buffer
        clean_stdin();


        if(read_from_stdin(strfmt, varor[i].namn, "Namm: ") == 0)
        {
            fprintf(stderr, "cannot continue reading\n");
            return i; // number of values added so far
        }

        // otherwise scanf might complain about leftovers in the input buffer
        clean_stdin();

        if(read_from_stdin("%d", &varor[i].saldo, "Saldo: ") == 0)
        {
            fprintf(stderr, "cannot continue reading\n");
            return i; // number of values added so far
        }

        if(read_from_stdin("%d", &varor[i].nummer, "Varunummer: ") == 0)
        {
            fprintf(stderr, "cannot continue reading\n");
            return i; // number of values added so far
        }

        putchar('\n');
    }

    return i;
}

您的打印功能看起来不错。但是你可以改善你的格式 输出,例如:

void view(struct vara varor[], int length)
{
    printf("%-30s %-10s %s\n", "Namn", "Saldo", "Nummer");

    for(int i=0; i<length; i++)
        printf("%-30s %-10d %d\n", varor[i].namn, varor[i].saldo, varor[i].nummer);
}

输出看起来像这样

Namn                           Saldo      Nummer
Jan                            129        1113232
Maria                          232        44342234

修改

正如chux在评论中指出的那样,我的read_from_stdin函数具有技术性 未定义的bevahiour,因为scanf需要int*指针%d 格式,我正在使用void*指针。

我想在这里引用chux:

  

chux在comments

中写道      

"%d"需要int *,而不是void *void *int*可以具有不同的宽度,编码

然而,在编写C代码15年后,我从来没有遇到过这种情况的常用架构 像这样的函数实际上会失败。除非您的目标架构不是异国情调,否则此功能将按照我的意图运行。