How to check for errors when inputting a number

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;
}
 
B

Ben Bacarisse

Albert said:
Are there any issues that you might raise about the following code
then?
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;
}

Why not just: 'if (fscanf(fp, "%d", &n) == 1) return n;'? This is a
serious question. What problem are you trying to solve by testing
that the number if followed by a newline?
 
A

Albert

Albert said:
Are there any issues that you might raise about the following code
then?
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;
    }

Why not just: 'if (fscanf(fp, "%d", &n) == 1) return n;'?   No idea.
<snip>
What problem are you trying to solve by testing
that the number if followed by a newline?
No idea.
 
B

Ben Bacarisse

Albert said:
Albert said:
Are there any issues that you might raise about the following code
then?
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;
    }

Why not just: 'if (fscanf(fp, "%d", &n) == 1) return n;'?  
No idea.

The you should use it. Look how simple it is.

There is a strong argument for writing simple code.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,607
Members
45,240
Latest member
pashute

Latest Threads

Top