跟我一起学c(练习4)

/**
c primer plus 6th Ch13
4.编写一个程序,不接受任何命令行参数或接受一个命令行参数。如果
有一个参数,将其解释为文件名;如果没有参数,使用标准输入(stdin)作
为输入。假设输入完全是浮点数。该程序要计算和报告输入数字的算术平均
值。
**/

#include <stdio.h>
#include <stdlib.h> // 提供 exit()的原型

int main(int argc, char* argv[])  //命令行参数存储在指针数组中
{
    FILE* fp = stdin; //FILE可以看成是一个类
    double num;
    int count = 0;
    double sum = 0.0;
    if(argc >= 2)
    {
        if((fp = fopen(argv[1], "r")) == NULL)
        {
            fprintf(stderr, "can`t open file %s.\n", argv[1]);
            exit(EXIT_FAILURE);
        }
    }
    
    //while(1 == fread(&num, sizeof(double), 1, fp)) //num = 0.0000, why? And can`t loop out if fp = stdin
    while(fscanf(fp, "%lf", &num) == 1)//fscanf()读到非"%lf"格式的输入时,返回0
    {
        //printf("DEBUG: num = %lf\n", num);
        count++;
        sum += num;
    }
    if(ferror(fp)) //因为读到文件结尾或者读写错误时,I/O函数都会返回EOF。区分方法:foef()返回非空表示读到文件结尾,ferror()返回非空表示读写出错。
    {
        printf("read file %s error.\n", argv[1]);
        exit(EXIT_FAILURE);
    }
    if(fclose(fp))
    {
        fprintf(stderr, "can`t close file %s.\n", argv[2]);
        exit(EXIT_FAILURE);
    }
    if(0 == count)
    {
        printf("No valid values.\n");
        return 0;
    }
    printf("%f\n", sum/count);
    
    return 0; //exit()和return的区别:前者会退出整个程序,后者只是将控制权交给上级代码。
}

本书给的参考答案:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char * argv [])
{
	FILE * fp;
	double n;
	double sum = 0.0;
	int ct = 0;
	if (argc == 1)
		fp = stdin;
	else if (argc == 2)
	{
		if ((fp = fopen(argv[1], "r")) == NULL)
		{
			fprintf(stderr, "Can't open %s\n", argv[1]);
			exit(EXIT_FAILURE);
		}
	}
	else
	{
		fprintf(stderr, "Usage: %s [filename]\n", argv[0]);
		exit(EXIT_FAILURE);
	}
	while (fscanf(fp, "%lf", &n) == 1)
	{
		sum += n;
		++ct;
	}
	if (ct > 0)
		printf("Average of %d values = %f\n", ct, sum / ct);
	else
		printf("No valid data.\n");
	
	return 0;
}
发布了15 篇原创文章 · 获赞 0 · 访问量 955

猜你喜欢

转载自blog.csdn.net/zimovv/article/details/104018975