2013-02-22 1 views
1

EMPLOYEE 레코드 파일을 만들려면이 프로그램을 사용하고 있습니다. 두 개의 구조체를 만들었습니다. 하나는 직원이라고하고 하나는 날짜라고 불렀습니다. EMPLOYEE 구조체에는 하나의 char 배열, 하나의 int, 6 개의 float 값 및 DATE (다른 Struct)가 있습니다. DATE 구조체는 세 개의 int 값 (월, 일, 년) 만 갖습니다.이진 파일에 구조체 배열 읽기, 채우기 및 쓰기

나는 person [1000]이라는 EMPLOYEE 유형의 배열을 만들었습니다.

여기 내 코드입니다. fwrite.c를 가리키는 Visual Studio에서 디버그 어설 션 오류가 계속 발생합니다. Expression : (Stream! = NULL). 구조체를 저장하려 한 적이 없어서 fred 나 fwite와 관련이 있다고 확신합니다.

이 함수의 시작 부분은 파일이 있고 비어 있지 않은 경우 배열을 채우는 것이므로 사용자가 배열에 데이터를 저장하기 시작할 때 아래 첨자가 업데이트됩니다. 여기에 몇 가지 다른 문제가 있지만 처음에는 먼저 읽고 쓰는 부분이 될 것입니다. 결과 FILE*를 지정하지 않고 한 줄에 그 쓸쓸한 모든 앉아

fopen("employeeRecords.bin", "ab+"); 

꽤 있습니다

다시 감사합니다,

마이크

void loadPayRoll(EMPLOYEE person[], int *i) 
{ 
    char sValidate[5] = "exit"; 
    FILE *f; 
    int count = 0; 

    f = fopen("emplyeeRecords.bin", "rb"); 
    if(f){ 
     while(fread(&person[*i], sizeof(person), 1, f) > 0){ 
      (*i)++; 
     } 
     fclose(f); 
    } 
    else { 

     while (strcmp(sValidate, person[*i].name)) { 

      fopen("employeeRecords.bin", "ab+"); 
      printf("Please enter name or type exit to return to main menu: "); 
      scanf("%s", person[*i].name);   //must use the '->' when passing by by refrence, must use '&' sign 
      flush; 

      if (!strcmp(sValidate, person[*i].name)) 
       break; 

      printf("\nPlease enter age of %s: ", person[*i].name); 
      scanf("%i", &person[*i].age); 
      flush; 
      printf("\nPlease enter the hourlyWage for %s: ", person[*i].name); 
      scanf("%f", &person[*i].hourlyWage); 
      flush; 
      printf("\nPlease enter the hours worked for %s: ", person[*i].name); 
      scanf("%f", &person[*i].hoursWkd); 

      if (person[*i].hoursWkd > 40) { 
       person[*i].regPay = person[*i].hoursWkd * 40; 
       person[*i].otHoursWkd = person[*i].hoursWkd - 40; 
       person[*i].otPay = person[*i].otHoursWkd * (person[*i].hourlyWage * 1.5); 
       person[*i].totalPay = person[*i].regPay + person[*i].otPay; 
      } 
      else { 
       person[*i].totalPay = person[*i].hoursWkd * person[*i].hourlyWage; 
      } 
      flush; 
      printf("\nEnter 2 digit month: "); 
      scanf("%i", &person[*i].payDate.month); //must use the '->' when passing by by refrence, must use '&' sign 
      flush; 
      printf("\nEnter 2 digit day: "); 
      scanf("%i", &person[*i].payDate.day); //must use the '->' when passing by by refrence, must use '&' sign 
      flush; 
      printf("\nEnter 4 digit year: "); 
      scanf("%i", &person[*i].payDate.year); //must use the '->' when passing by by refrence, must use '&' sign 
      flush; 
      fwrite(&person[*i], sizeof(person), 1, f); 
      fclose(f); 
      (*i)++; 
     } 
    } 
}//end function loadPayRoll 
+1

왜 내가 포인터인지 확실하지 않습니다. 색인으로 사용하는 것 같습니다. 그것은 보통 정수 여야합니다. 그 외에도 다음을 읽어보십시오. http://stackoverflow.com/questions/3711233/is-the-struct-hack-technically-undefined-behavior –

+0

루프 내부에서 파일을 열고 닫을 필요가 없습니다. 그냥 루프 전에 열고 닫으십시오. –

+0

i는 다른 함수에 의해 전달 되었기 때문에 포인터이지만, 이제는 그것에 대해 생각합니다. 그것은 다른 함수가 끝 첨자 값을 알아야 할 필요가 없다고 생각할 때 까다로운 시각으로 보지 않을 수도 있습니다. –

답변

3

나는이 확신 조금 문제가 있습니다. 예를 들어 다른 문제가 많이 있습니다.

flush; 

그게 무슨 뜻인지 잘 모르겠다. 아마도 당신은 의미 :

f 이제까지 실제로 제대로 할당 된 가정
fflush(f); 

,

그리고에 주석이 지적했듯이, 당신은 필요에 따라 루프, 데이터를 쓰기 시작 전에 파일 을 열어야합니다

, 루프가 끝난 후 닫는다.

+0

예, f = fopen()을 넣는 것을 잊었습니다. 플러시는 내 프로그램의 상단에 정의됩니다. –

+0

나는주의를 기울이는 동안. 구조체의 특정 값을 나중에 프로그램에서 읽으려는 경우에도 한 번에 이진 파일에 구조체를 쓸 수 있습니까? 또 다른 기능에서는 각 인물의 플로트 사람 [i] .totalPay 값만 가져올 수 있기를 원합니다. –

+0

@MichaelBrooks 무엇이든지간에 조언하지 않겠습니다. 결국 바이트 *의 버퍼 *를 사용하여 데이터를 적절히 패킹하고 압축을 푸는 연습을해야합니다. struct를 mem-write 할 때 엔디안, 패킹, 정렬 등의 차이가 발생할 수 있습니다. 데이터를 다시 읽어 들일 때마다. 데이터를 적절하게 (그리고 * 이동 가능하게) 쓰고 읽는 쓰기/읽기 함수 세트를 정의하면 목표 파일 스트림으로 이동하면 장기적으로 더 나아질 것입니다. – WhozCraig