繁体   English   中英

结构中的数组和C中的文件存在问题

[英]Problems with arrays within structures and files in C

我正在尝试使用C语言中的结构来存储课程名称的信息以及我上课的日期。存储名称不是问题。 当我尝试在数组中存储多天(工作日作为整数,即星期一= 1)时,会出现问题。

这就是我所拥有的:

#include<stdio.h>
#include<string.h>

struct lessons{

   char name[20];
   int day[3];

};

changelessons(){

    int i, k;
    struct lessons give[1], receive[1];

    FILE *fptr;

    fptr = fopen("lessons","wb");

    fflush(stdin);

    printf("\n\t ~ Change lessons ~");
    printf("\n\nWhat's the lesson called?: ");
    gets(give[0].name);

    printf("\nHow many days do you have it?\n");
    scanf("%d", &k);

    for(i = 0; i < k; i++); {  // Asks the weekday number for each day you have the lesson
        printf("What day is lesson %d?: ", i);
        scanf("%d", &give[0].day[i]);
    }

    fwrite(give, sizeof(give), 1, fptr);
    fclose(fptr);

    fptr = fopen("lessons", "rb");
    fread(receive, sizeof(receive), 1, fptr);

    printf("\n\t ~ Updated information: ~\n\nLesson name: %s\nDay: %d", receive[0].name, receive[0].day[1]);

    for(i = 1; i < k; i++); {  // Prints the extra weekdays if there are any
        printf(", day: %d", receive[0].day[i]);
    }

    printf("\n\n");

    fclose(fptr);
}

showlessons(){

    struct lessons give[1], receive[1];

    FILE *fptr;

    fptr = fopen("lessons", "rb");
    fread(receive, sizeof(receive), 1, fptr);

    printf("\t ~ Current information: ~ \n\nLesson name: %s\nDay: %d\n\n", receive[0].name, receive[0].day[0]);

}

int main(){

  showlessons();
  changelessons();

  return 0;
}

此外,在第一个for循环中,它只会循环一次,而不管k等于什么。

在此先感谢您的帮助!

for(i = 0; i < k; i++);

应该

for(i = 0; i < k; i++)

额外的半结肠是一个问题。 您的循环代码不是循环的一部分。 半冒号终止循环。

nicomp指出了最明显的错误。

但我还想指出我的代码中的一些问题:

  1. fflush(stdin); 这是错误的,未定义的行为。 fflush用于刷新输出流, stdin是输入流。 请参阅使用fflush(stdin)

    我知道在Windows中fflush(stdin)清除输入缓冲区,但我强烈建议不要使用它,因为在中继仅在一个操作系统中可用的功能时会丢失可移植性。 如果您不关心可移植性,请使用它。 如果你使用它,因为scanf在输入缓冲区中留下了东西,请改用:

     int c; while((c = getchar()) != '\\n' && c != EOF); 

    这是便携式的。

  2. 永远不会在2018年使用getsgets是一个不安全,危险的函数,已在C99中弃用,并且有充分的理由:它不考虑缓冲区的大小,如果输入的文本比缓冲区可以存储的长,它会溢出缓冲区。 这是一个等待发生的事故。 所以,永远不要gets试。 请改用fgets ,如果您不想使用换行符,可以将其删除:

     fgets(give[0].name, sizeof give[0].name, stdin); give[0].name[sizeof(give[0].name) - 1] = 0; // remove possible newline 
  3. 为什么要声明一个尺寸为1的struct lessons数组? 重点是什么? 你不需要一个数组。 你可以像这样写:

     struct lessons give, receive; ... printf("\\n\\nWhat's the lesson called?: "); fgets(give.name, sizeof give.name, stdin); give.name[strcspn(give.name, "\\n")] = 0; ... fwrite(&give, sizeof give, 1, fptr); fclose(fptr); ... fptr = fopen("lessons", "rb"); fread(&receive, sizeof receive, 1, fptr); 

    另外不要忘记检查fwritefread的返回值。

  4. 检查fopen的返回值,如果返回NULL ,则不能使用freadfwrite 打印错误值并返回/退出。

  5. stdout是缓冲的,当你用printf写它时,它不一定会立即在屏幕上打印字符。 一个例外是当stdout连接到终端并且换行符是用printf写的。 对于用户交互,这很好,因为用户会立即看到输出。 这就是大多数人在文本中打印换行符的原因。

    如果你不这样做,但你仍然希望用户立即看到输出,那么这次你应该使用fflush

      printf("What day is lesson %d?: ", i); fflush(stdout); scanf("%d", &give[0].day[i]); 

    我不知道是否保证scanf在连接到终端时刷新stdout ,无论在最后不打印换行符时使用fflush(stdout)都是好的做法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM