为什么我在显示数据后得到垃圾值

时间:2017-08-26 13:03:18

标签: c arrays database structure

  1. 我在显示记录时收到垃圾值。

  2. 我必须使用结构数组而不使用指针在C中创建学生数据库。

  3. 还有其他方法吗?

  4. 如何使用结构数组?

    #include <stdio.h>
    
    struct student {
        char first_name[10],last_name[10];
        int roll;
        char address[20];
        float marks;
    };
    
    void accept(struct student);
    void display(struct student);
    
    void main() {
        struct student S[10];
        int n, i;
        printf("Enter the number of records to enter : ");
        scanf("%d", &n);
    
        for (i = 0; i < n; i++) {
            accept(S[i]);
        }
    
        for (i = 0; i < n; i++) {
            display(S[i]);
        }
    }
    
    void accept(struct student S) {
        scanf("%s", S.first_name);
        scanf("%s", S.last_name);
        scanf("%d", &S.roll);
        scanf("%s", S.address);
        scanf("%f", &S.marks);
    }
    
    void display(struct student S) {
        printf("\n%s", S.first_name);
        printf("\n%s", S.last_name);
        printf("\n%d", S.roll);
        printf("\n%s", S.address);
    }
    

2 个答案:

答案 0 :(得分:1)

C中的所有内容都是按值传递。这意味着您正在修改堆栈帧中的变量副本,而作为参数传递的实际变量保持不变。

您必须将指针传递给要在函数中修改的变量。

// Function declaration
void accept(struct student *);

// Call
accept(&S[i]);

// Usage in function via dereference operator
scanf("%s",S->first_name);

如果您想输入未知数量的记录,则应使用VLA (since c99)或动态分配结构。

<强> VLA

scanf("%d",&n);
struct student S[n];

动态调用

scanf("%d",&n);
struct student * S = malloc(sizeof(struct student) * n);

因为在你的情况下,如果用户输入了更多的9条记录,你在界限之外触摸,这些记录具有未定义的行为。

答案 1 :(得分:0)

您的代码中存在多个问题:

  • main
  • int main(void)标准原型是calloc
  • 您应该使用accept动态分配数组。
  • 您应该将结构指针传递给displayaccept函数,而不是按值传递结构。按值传递目标结构是不正确的,因为main函数无法修改scanf()函数中的结构,该结构保持未初始化并导致显示垃圾。请注意,访问未初始化数据实际上是未定义的行为,因此程序可能会以更糟糕的方式运行。
  • 您应该为scanf()提供存储到字符数组中的最大参数数量,以避免潜在的缓冲区溢出。
  • 您应该验证%[^\n]的返回值,以避免无效输入时出现未定义的行为。
  • 您可以使用#include <stdio.h> #include <stdlib.h> struct student { char first_name[10], last_name[10]; int roll; char address[20]; float marks; }; void accept(struct student *sp); void display(const struct student *sp); int main(void) { struct student *S; int n, i, j; printf("Enter the number of records to enter : "); if (scanf("%d", &n) != 1) return 1; S = calloc(sizeof(*S), n); if (S == NULL) { return 1; } for (i = 0; i < n; i++) { accept(&S[i]); } for (i = 0; i < n; i++) { display(&S[i]); } free(S); return 0; } void accept(struct student *sp) { if (scanf("%9s%9s&d %19[^\n]%f", sp->first_name, sp->last_name, &sp->roll, sp->address, &sp->marks) != 5) { printf("missing input\n"); exit(1); } } void display(const struct student *sp) { printf("%s\n", sp->first_name); printf("%s\n", sp->last_name); printf("%d\n", sp->roll); printf("%s\n", sp->address); printf("%f\n", sp->marks); printf("\n"); } 扫描集来允许地址字段中的嵌入空格。

以下是修改后的版本:

from __future__ import unicode_literals

from django.db import models

from wagtail.wagtailcore.models import Page
from wagtail.wagtailcore.fields import RichTextField
from wagtail.wagtailadmin.edit_handlers import FieldPanel

from blog.models import BlogPage


class HomePage(Page):
    def blogs(self):
        blogs = BlogPage.objects.all()
        blogs = blogs.order_by('-date')
        return blogs