A
Albert
Mine because I write it, I understand it, and it does not have any
serious errors in it. I am sure other people might prefer yours
(errors corrected) but I suspect they have long since abandoned this
sub thread.
Are there any issues that you might raise about the following code
then? I fetch numbers from a file and terminate when I found a zero
inputted. For the most part, it's the 3n + 1 problem where we report
the number of steps needed to reach 1.
#include <stdio.h>
#include <stdlib.h>
enum { true = 1, false = 0, ENDINPUT = 0 };
#define bool int
FILE* openfile(const char *, const char *);
void closefile(FILE *);
int read_num(FILE *);
void pAns(int, FILE *);
bool isEven(int);
bool isPos(int);
int main()
{
int num, nsteps;
int i, j; // counters //
FILE* in = openfile("hailin.txt", "r");
FILE* out = openfile("hailout.txt", "w");
while ((num = read_num(in)) != ENDINPUT &&
isPos(num)) {
nsteps = 0;
while (num != 1) {
nsteps += 1;
if (isEven(num)) {
num /= 2;
} else {
num = num * 3 + 1;
}
}
pAns(nsteps, out);
}
closefile(in);
closefile(out);
return EXIT_SUCCESS;
}
FILE* openfile(const char *filename, const char *mode)
{
FILE* x;
if ((x = fopen(filename, mode)) == NULL) {
fprintf(stderr, "Error opening file.\n");
exit(EXIT_FAILURE);
}
return x;
}
void closefile(FILE *fp)
{
if (fclose(fp) != 0) {
fprintf(stderr, "Error closing file\n");
exit(EXIT_FAILURE);
}
}
int read_num(FILE *fp)
{
static unsigned long ncalls = 0;
int n;
ncalls += 1;
char first[2];
if (fscanf(fp, "%d%1[\n]", &n, first) == 2) {
return n;
}
fprintf(stderr, "Input error on call no. %lu to read_num\n",
ncalls);
exit(EXIT_FAILURE);
}
void pAns(int ans, FILE *fp)
{
if (fprintf(fp, "%d\n", ans) < 0) {
fprintf(stderr, "Error occured writing answer to file.\n");
exit(EXIT_FAILURE);
}
}
bool isEven(int x)
{
return x%2 == 0;
}
bool isPos(int x)
{
return x > 0;
}