簡體   English   中英

打印一個結構數組,C

[英]print an array of structs, C

我想打印我的結構體數組,但我不斷遇到分段錯誤,我在做什么錯? 我首先使用另一個函數來讀取數據。 然后,我想查看我剛才輸入的內容。

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

我認為問題的根源是您的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函數在技術上沒有定義行為,因為scanf期望%d格式為int*指針,而我使用的是void*指針。

我想在這里引用chux:

chux在評論中寫道

"%d"期望一個int * ,而不是一個void * void *int*可以具有不同的寬度,編碼

但是,在編寫C代碼15年之后,我再也沒有遇到過這種情況的通用架構,並且這樣的功能實際上會失敗。 除非您的目標體系結構不是異國情調的體系結構,否則此功能將按我的預期工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM