Last Updated: 2019-02-07 Thu 14:27

# CSCI 2021: C Text and Binary I/O

## 1 Rationale

The below Problem/Solutions were part of a past lab which demonstrated some basic techniques and common problems associated with C's I/O functions, particularly `fread()` and `fwrite()`. They are provided to supplement the treatment of these topics in lecture and support development on Assignment 1.

C reference material on `fread() / fwrite()` for binary I/O. For a full reference on these functions, you may consult the manual pages on a system or online here:

## 2 Problems / Solutions

### A

```  FILE *fin = fopen(...,"r");
int buf;             // store 4 ints from file in this array
fread(buf, 4, 1, fin);  // want to read 4 ints from fin into buf (error)
```

Describe why the marked line is an error and provide a correction.

#### Solution   solution

The 2nd argument of `fread()` is the size of each element to be read while the third argument is how many to read. If the intent is to read 4 integers, ensure that the proper size is set using `sizeof(int)` and the number of ints to read is specified as below.

```  fread(buf, sizeof(int), 4, fin);
```

Alternatively, one could read the integers in one at a time as in the following.

```for(int i=0; i<4; i++){
}
```

### B

Describe why the below code does not actually write the entire `double` array `buf` to a file properly.

```  FILE *fout = fopen(...,"w");
int length = ...;
double *buf = malloc(length*sizeof(double));
// fill in buf with values
for(int i=0; i<length; i++){              // write doubles from buf one at a time
fwrite(buf, sizeof(double), 1, fout);   // error
}
```

#### Solution   solution

One `double` is being written at each call to `fwrite()`. Since the pointer `buf` does not change, it will always be the 0th double in the array. To fix this, advance forward in `buf` by providing an offset using code like:

```    fwrite(&buf[i], sizeof(double), 1, fout);
// OR
fwrite(buf+i,  sizeof(double), 1, fout);
```

### C

Describe why the following code could potentially cause unexpected problems.

```  FILE *fin = fopen(...,"r");
char buf;             // store up to 100 characters
int pos = 0;
while(1){
int result = fscanf(fin, "%d", &buf[pos]);
if(result == EOF){
break;
}
pos++;
}
// error in logic, may overflow buf: why?
```

#### Solution   solution

Reading an unknown number of characters into a buffer size 100 is dangerous. If there are more than 100 characters, the ready may overflow the buffer clobbering arbitrary memory locations. This may corrupt other data or cause a segmentation fault.

Fix with either a limit like:

```  while(pos < 100){
int result = fscanf(fin, "%d", &buf[pos]);
if(result == EOF){
break;
}
pos++;
}
```

or by counting and allocating using malloc() as per the assignment.

### D

Describe why the code below gets a compiler error.

```// read two binary ints from given file, return pointer to them
FILE *fin = fopen(fname,"r");
int buf;
fclose(fin);
return buf;  // compile error
}
```

#### Solution   solution

You cannot return a stack allocated array from a function. Use malloc() for this as in:

```// read two binary ints from given file, return pointer to them