de******@dteenergy.com (KevinD) wrote:
# assumption: I am new to C and old to COBOL
#
# I have been reading a lot (self teaching) but something is not sinking
# in with respect to reading a simple file - one record at a time.
# Using C, I am trying to read a flatfile. In COBOL, my simple file
# layout and READ statement would look like below.
#
# Question: what is the standard, simple coding convention for reading
# in a flatfile - one record at a time?? SCANF does not work because of
# spaces; I tried FGETS and STRUCT to emulate my COBOL perspective but
# that does not work (though I may have coding this wrong). C likes to
# deliver data in streams but FGETS is akin to reading a single record.
#
# I know I am missing something that is very simple but the examples
# that I have come across avoid this simple scenario. Please explain -
# an example would be great.
#
# thanks
# kevin
#
#
# ......
# 01 employee-record.
# 03 emp-id pic 9(5).
# 03 emp-dept pic x(5).
# 03 emp-name.
# 05 emp-name-last pic x(20).
# 05 emp-name-first pic x(20).
# 03 emp-hire-date.
# 05 emp-hire-date-mm pic 9(2).
# 05 emp-hire-date-dd pic 9(2).
# 05 emp-hire-date-yy pic 9(4).
On most C implementations you can overlay a struct of just char[] fields
on a char string without worrying about padding. However to be safer and
to do the type conversions (most C implementation require decimal to binary
conversion to do arithmetic and zero byte terminated strings), I would be
inclined to write a parser routine.
struct employee_record {
int emp_id;
char emp_dept[5+1]; /*+1 for zero byte terminator*/
struct {
char emp_name_last[20+1];
char emp_name_first[20+1];
} emp_name;
struct {
int emp_hire_date_mm;
int emp_hire_date_dd;
int emp_hire_date_yy;
} emp_hire_date;
};
static long pic9(int n,char *line,int *pos) {
long num; char *t = malloc(n+1); memcpy(t,line+*pos,n); t[n] = 0;
*pos += n;
num = strtol(t,0,10); free(t);
return num;
}
static void picx(char *string,int n,char *line,int *pos) {
memcpy(string,line+*pos,n); string[n] = 0;
*pos += n;
}
static int read_employee_record(
FILE *employee_flatfile,
struct employee_record *employee_record
) {
char line[5+5+20+20+2+2+4+2];
if (fgets(line,sizeof line,employee_flatfile)) {
char *nl = strchr(line,'\n');
if (nl) *nl = 0;
if (strlen(line)==sizeof line-2) {
int pos = 0;
employee_record->emp_id = pic9(5,line,&pos);
picx(employee_record->emp_dept,5,line,&pos);
picx(employee_record->emp_name.emp_name_last,20,line,&pos);
picx(employee_record->emp_name.emp_name_first,20,line,&pos);
employee_record->emp_hire_date.emp_hire_date_mm = pic9(2,line,&pos);
employee_record->emp_hire_date.emp_hire_date_dd = pic9(2,line,&pos);
employee_record->emp_hire_date.emp_hire_date_yy = pic9(4,line,&pos);
return 0;
}else
return -1;
}else
return -1;
}
# read employee-flatfile into employee-record.
read_employee_record(employee_flatfile,&employee_r ecord);
--
SM Ryan
http://www.rawbw.com/~wyrmwif/
Haven't you ever heard the customer is always right?