Hello to you all ,

I am having a little trouble in C , working with Files.
for some reason , it doesnt copy to output file the first letter and jumps
over 3 digits of the last number in the file .

whats wrong , i cant find it .

yotam

P.S - source and Input.txt included

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

typedef struct { // Student Structure //
char name[15];
long id;
float avg;
long hw_submit;
} student;

typedef struct { //University Structure //
student* ptr;
} university;
static void forcefloat (float *p)    /* fixing scanf floating point */
{
 float f = *p;
 forcefloat(&f);
}

char show_menu();
int make_file(FILE *in,university *un);
void write_file(FILE *out,university *un,int num);

void main()
{
university univ;
char user_choice;
FILE *in,*out;
int num_of_std;

while (user_choice!='z') {
user_choice=show_menu();
printf("chosen Key is %c \n",user_choice);
switch (user_choice) {
   case 'a':
	{
	in=fopen("input.txt","r+");
	if (in==NULL)
		{
		fprintf(stderr,"can't open file");
		getch();
		break;
		}
	num_of_std=make_file(in,&univ);
	fclose(in);
	printf("finished kelet\n");
	break;
	}
   case 'b':
	{
	if ((out=fopen("output.txt","wt"))==NULL)
		{
		fprintf(stderr,"can't open file");
		getch();
		break;
		}

	write_file(out,&univ,num_of_std);
	fclose(out);
	printf("finished writing file , i am having a coffee break \n");
	break;
	}
   }
 }
}

// FUNCTIONS //
char show_menu()
  {
  char key_strike;

   printf("Welcome to University system \nChoose Operation :\n");
   printf(" 'a' - Create File in Current Path and start Input \n");
   printf(" 'b' - Create File in Current Path according to HW submission \n");
   printf(" 'c' - Show Factored Grades of students \n");
   printf(" 'z' - Exit Program and have a cup of coffee \n\n\n\n\n" );
   key_strike=getchar();
   return key_strike;
  }

int make_file(FILE *in,university *un)
  {
  int i=0,count=0;

  while (getc(in)!=EOF)
   {
   fscanf(in,"%s",un->ptr[i].name);
   fscanf(in,"%ld",&un->ptr[i].id);
   fscanf(in,"%f",&un->ptr[i].avg);
   fscanf(in,"%ld",&un->ptr[i].hw_submit);
   count++;
   i++;
   if (un->ptr==NULL) un->ptr=(student*)realloc(un->ptr,(count+1)*sizeof(student));
   }
return count;
}

void write_file(FILE *out,university *un,int num)
{
int i;
for(i=0;i<num;i++)
fprintf(out,"student : %s %ld %.2f %ld\n",un->ptr[i].name,un->ptr[i].id,un->ptr[i].avg,un->ptr[i].hw_submit);
}
Nir 32251 99.80 11001
Ely 12347 77.89 01111
Moshe 45321 50.34 11111
Avi 31456  49.78 00011

> void main
main returns int

> char user_choice;
> while (user_choice!='z')
This variable is uninitialised at the point you first use it.

> university univ;
This isn't initialised either.
Which is very important when you get to make_file(), since you do
- dereference an uninitialised pointer
- try and realloc an uninitialised pointer

> if (un->ptr==NULL) un->ptr=(student*)realloc(un->ptr,(count+1)*sizeof(student));
The test serves no purpose, since at best it only extends the array once.

In main(), you need this to start off with a NULL pointer university univ = { 0 }; And this function needs to be something like

int make_file(FILE *in,university *un) {
  char buff[BUFSIZ];
  int  count=0;

  while ( fgets( buff, sizeof buff, in ) != NULL ) {
    student s;
    if ( sscanf( buff, "%s %ld %f %ld",
                 s.name, &s.id, &s.avg, &s.hw_submit ) == 4 ) {
      /* success decode, extend array and copy the info */
      void *temp = realloc( un->ptr, (count+1)*sizeof(student) );
      if ( temp != NULL ) {
        un->ptr = temp;          /* update array */
        un->ptr[count] = s;      /* copy data */
        count++;                 /* one more stored */
      } else {
        /* no more room, return with what we have */
        return count;
      }
    } else {
      /* that line didn't make sense, report it */
      fprintf( stderr, "Bad line %s", buff );
    }
  }
  return count;
}

> void main
main returns int

> char user_choice;
> while (user_choice!='z')
This variable is uninitialised at the point you first use it.

> university univ;
This isn't initialised either.
Which is very important when you get to make_file(), since you do
- dereference an uninitialised pointer
- try and realloc an uninitialised pointer

> if (un->ptr==NULL) un->ptr=(student*)realloc(un->ptr,(count+1)*sizeof(student));
The test serves no purpose, since at best it only extends the array once.

In main(), you need this to start off with a NULL pointer university univ = { 0 }; And this function needs to be something like

int make_file(FILE *in,university *un) {
  char buff[BUFSIZ];
  int  count=0;

  while ( fgets( buff, sizeof buff, in ) != NULL ) {
    student s;
    if ( sscanf( buff, "%s %ld %f %ld",
                 s.name, &s.id, &s.avg, &s.hw_submit ) == 4 ) {
      /* success decode, extend array and copy the info */
      void *temp = realloc( un->ptr, (count+1)*sizeof(student) );
      if ( temp != NULL ) {
        un->ptr = temp;          /* update array */
        un->ptr[count] = s;      /* copy data */
        count++;                 /* one more stored */
      } else {
        /* no more room, return with what we have */
        return count;
      }
    } else {
      /* that line didn't make sense, report it */
      fprintf( stderr, "Bad line %s", buff );
    }
  }
  return count;
}

I did so , however , only the first name was fixed .... how bizzare.
1. what does "buff" stands for , after all it has no Value.
2.BUFSIZ shoulde be defined or resized each reading from source file?
3.how can get rid of the double menu display?
4.is there a way to write to target file so it wont skip chars?

thanx salem

1. what does "buff" stands for , after all it has no Value.
buff is short for buffer.

2.BUFSIZ shoulde be defined or resized each reading from source file?
No, it is a fixed constant declared in stdio.h (for an ANSI-C compiler anyway).
You are using an ANSI-C compiler and not some ancient fossil like TurboC.

3.how can get rid of the double menu display?
Don't use getchar(), scanf(), getc() to read a single character.
Use fgets() to read a line from stdin, then read what you need from the buffer.
It's just like my use of fgets() in the previous post.

4.is there a way to write to target file so it wont skip chars?
I've no idea - post the problem code.

This article has been dead for over six months. Start a new discussion instead.