C读取文件,结构和无限循环

时间:2016-01-28 18:50:57

标签: c

我编写了一个收集用户数据并将其保存到文件中的程序。在他想要查看文件的那一刻,程序循环并仅显示第一条记录。我不知道这个错误是由什么造成的。

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

FILE *fptr;  

struct notification {
    char name[50];
    char lastname[50];
    char price[10];
    char descreption[100];
}notification;

void insertRecord()
{
    fptr=fopen("G:\\file.txt","a+");

    fflush(stdin);

    printf("Podaj imie: ");
    gets(notification.name);

    printf("Podaj nazwisko: ");
    gets(notification.lastname);

    printf("Podej cene: ");
    gets(notification.price);

    printf("Podaj opis usterki: ");
    gets(notification.descreption);

    strcat(notification.descreption,"\n");


    if(fwrite(&notification,sizeof(notification),1,fptr) != 1)
    {
        perror("Blad: ");
    } else{

        printf("Dane dodane poprawnie\n");

    }
    fclose(fptr);
}

void readDatabase()
{

    struct notification *object2=malloc(sizeof(struct notification));
    fptr=fopen("G:\\file.txt","rb");

    fread(object2,sizeof(struct notification),1,fptr);

    while(!feof(fptr))
    {

        printf("Imie: %s\n", object2->name);
        printf("Nazwisko: %s\n", object2->lastname);
        printf("Cena: %s\n", object2->price);
        printf("Opis: %s\n", object2->descreption);
        printf("==========\n");
    }

    fclose(fptr);
}

int main() {
    int i,option=0,check=0;

    do{
        printf("1) Dodaj rekord do bazy \n");
        printf("2) Odczytaj rekordy z bazy \n");
        printf("0) Zakoncz program \n");

        scanf("%d", &option);

        switch (option)
        {
            case 1:
                insertRecord();
                break;
            case 2:
                readDatabase();
                break;
            default:

                break;
        }    
    }while(check == 0); //petla dziala dopóki zmienna check bedzie równa 0

}

编辑:

纠正insertRecord功能:

void insertRecord()
{
    fptr=fopen("G:\\file.txt","a+");

    fflush(stdin);

    struct notification *obj = malloc(sizeof(struct notification));


    printf("Podaj imie: ");
    gets(obj->name);

    printf("Podaj nazwisko: ");
    gets(obj->lastname);

    printf("Podej cene: ");
    gets(obj->price);

    printf("Podaj opis usterki: ");
    gets(obj->descreption);

    strcat(notification.descreption,"\n");


    if(fwrite(obj,sizeof(struct notification),1,fptr) != 1)
    {
        perror("Blad: ");
    } else{

        printf("Dane dodane poprawnie\n");

    }
    free(obj);
    fclose(fptr);
}

现在ALL显示并插入OK,但是在file.txt中我看到中文字符,为什么?

4 个答案:

答案 0 :(得分:1)

移动此行:

fread(object2,sizeof(struct notification),1,fptr);

在你的while循环中。

答案 1 :(得分:1)

scanf("%d", &option);后跟gets()会导致麻烦。第一个不会消耗数字之后的'\n',而第二个只读取短行'\n'

请勿使用scanf()。不要使用gets()。使用fgets(),然后解析输入。

答案 2 :(得分:1)

readDatabase功能

中存在各种问题
  • while(!feof)-is-always-wrong
  • fread需要在循环中。
  • 您不需要malloc内存,但如果您执行了malloc内存,那么当您完成内存后,您应free
  • 您始终需要检查fopen的返回值,因为它可以并且确实失败,例如因为找不到文件

考虑到所有这些,readDatabase函数应如下所示

void readDatabase( void )
{
    struct notification object2;

    if ( (fptr = fopen("G:\\file.txt","rb")) == NULL )
    {
        printf( "File not found\n" );
        return;
    }

    while ( fread( &object2, sizeof(struct notification), 1, fptr ) == 1 )
    {
        printf("Imie: %s\n", object2.name);
        printf("Nazwisko: %s\n", object2.lastname);
        printf("Cena: %s\n", object2.price);
        printf("Opis: %s\n", object2.descreption);
        printf("==========\n");
    }

    fclose(fptr);
}

答案 3 :(得分:0)

默认情况下,

scanf()将在输入流中保留新的行字符。你可以使用getchar()函数清除这个新行字符,或者像这样刷新输入缓冲区。

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

但不要使用fflush(stdin),因为如果文件流用于输入,如stdin,则行为未定义,因此使用fflush()清除键盘输入是不可接受的。像往常一样,有一些例外情况,请检查编译器的文档,看看它是否有一个(非便携式)方法来刷新输入。