1054 求平均值 && sscanf和sprintf的详细用法

题目链接:

由于输入可能有字母或是多个小数点,因此采用字符数组的方式输入(%s)。

本题主要的难点在于判断每一个输入数据是否合法。

分析
使用sscanf和sprintf函数~
sscanf() – 从一个字符串中读进与指定格式相符的数据
sprintf() – 字符串格式化命令,主要功能是把格式化的数据写入某个字符串中

#include <bits/stdc++.h>
using namespace std;
int main() {
    int n, cnt = 0;
    char a[50], b[50];
    double temp = 0.0, sum = 0.0;
    cin >> n;
    for(int i = 0; i < n; i++) {
        scanf("%s", a);
        sscanf(a, "%lf", &temp);//把字符串a中的浮点数取出
        sprintf(b, "%.2f", temp);//将浮点数temp保留两位小数读到字符串b中(此时字符串b为“看起来是两位小数”的字符串)
        int flag = 0;
        for(int j = 0; j < strlen(a); j++)//因为是“最多精确到小数点后2位”,所以a的字符串长度一定>=b的,所以循环结束为到strlen(a)为止。
        {if(a[j] != b[j]) flag = 1;}//如果a[j]!=b[j],说明a不是两位小数以内的实数,输出~~~。
        if(flag || temp < -1000 || temp > 1000) {
            printf("ERROR: %s is not a legal number\n", a);
            continue;//直接开始下一步循环
        } else {//输入合法则求和,且计数器++
            sum += temp;
            cnt++;
        }
    }
    /*模拟*/
    if(cnt == 1)
        printf("The average of 1 number is %.2f", sum);
    else if(cnt > 1)
        printf("The average of %d numbers is %.2f", cnt, sum / cnt);
    else
        printf("The average of 0 numbers is Undefined");
    return 0;
}

验证程序:

int n, cnt = 0;
    char a[50], b[50];
    double temp = 0.0, sum = 0.0;
    cin >> n;
    for(int i = 0; i < n; i++) {
        scanf("%s", a);
        sscanf(a, "%lf", &temp);
        sprintf(b, "%.2f", temp);
    	printf("a = %s , b = %s\n\n\n", a, b);

输出结果

补充:

1、sscanf函数(包含于#include <cstdio>头文件中):

1、作用:从一个字符串中读进于指定格式相符的数据。利用它可以从字符串中取出整数、浮点数和字符串。
2、函数原型int sscanf(const char *str, const char *format,......);
3、和scanf的区别:scanf是以键盘作为输入源,sscanf是以字符串作为输入源。
4、用法概述
sscanf()会将参数str的字符串根据参数format字符串来转换格式并格式化数据。转换后的结果存于对应的参数内。
5、函数返回值:成功则返回参数数目,失败则返回0

例1:取指定长度的字符串/读入字符串:
#include<cstdio>
int main()
{
	char str[100];
	sscanf("12345","%4s",str);
	printf("%s\n",str);
	return 0;
}
//输出1234

#include<cstdio>
int main()
{
	char str[100];
	sscanf("12345","%s",str);
	printf("%s\n",str);
	return 0;
}
//输出12345

#include<cstdio>
int main()
{
 	char str1[100], str2[100], str3[100];
  	gets(str1);
  	sscanf(str1,"%s%s",str2,str3);
  	printf("%s %s\n",str2,str3);
	return 0;
}
//输入xinxi love you
//输出xinxi love
例2:整型数字/浮点数转换:
2.1:
int year, month, day;
 
int converted = sscanf("20191103", "%04d%02d%02d", &year, &month, &day);
printf("converted = %d, year = %d, month = %d, day = %d\n", converted, year, month, day);

输出:

converted = 3, year = 2019, month = 11, day = 03

"%04d%02d%02d"是用来解析字符串的格式,%表示格式转换的开始,d表示转换为一个整数,04作为d的修饰,表示这是一个长度为4位的整数,不足4位时以0补齐。

例子返回结果等于3,表示有3个数据成功转换,转换成功数目同时取决于被解析的字符串以及其转换格式,如果我们把例子中的格式改为"%04d%02d",那么sscanf将只返回2,day的数值不会被sscanf更改。

2.2:
double longitude, latitude;
int converted = sscanf("113.123456789 31.123456789", "%lf %lf", &longitude, &latitude);
printf("converted = %d, longitude = %.9lf, latitude = %lf/n", converted, longitude, latitude);

输出:

converted = 2, longitude = 113.123456789, latitude = 31.123457
例3:*的用法: %* d和%* s加了(*)表示跳过此数据不读入(也就是不把此数据读入参数中)
3.1:
char str[100];
sscanf("123456abcdedf", "%*[0-9]%[a-z]", str);
printf("str = %s\n", str);

//输出str = abcdef
3.2:
#include <cstdio>
int main()
{
	char str[100];
	sscanf("1234abcd", "%*d%s", str);
	printf("%s\n",str);
	return 0;
}

//输出abcd
例4:^的用法
4.1:取到指定字符为止的字符串
#include<cstdio>
int main()
{
	char str[100];
	sscanf("1234+abc","%[^+]",str);
	printf("%s\n",str);
	return 0;
}

//输出1234
4.2:取到指定字符集为止的字符串
char str[100];
sscanf("123456abcdedf", "%[^a-z]", str);
printf("%s\n", str);

//输出123456
4.3:取仅包含指定字符集的字符串。(取仅包含数字和小写字母的字符串,是取得连续的字符串)。
#include<cstdio>
int main()
{
	char str[100];
	sscanf("123456abcdefBFRGTY7890","%[1-9a-z]",str);
	printf("%s\n",str);
	return 0;
}

//输出123456abcdef

2、sprintf函数(包含于#include <cstdio>头文件中):

由于 sprintf 跟 printf 在用法上几乎一样,只是打印的目的地不同而已,前者打印到字符串中,后者则直接在命令行上输出。这也导致 sprintf 比 printf 有用得多。所以本文着重介绍 sprintf,有时也穿插着用用 snprintf。

函数原型:

int sprintf( char *buffer, const char *format [, argument]);

用法详述

1、格式化数字字符串

sprintf最常见的应用之一莫过于把整数打印到字符串中,所以,sprintf 在大多数场合可以替代itoa(把一个整数转换为字符串)。如:

1、 把整数123打印成一个字符串保存在s中。

sprintf(s, "%d", 123);  // 产生"123"

2、可以指定宽度,不足的左边补空格:

sprintf(s, "%8d%8d", 123, 4567); // 产生:"    123    4567"

(当然也可以左对齐):

sprintf(s, "%-8d%8d", 123, 4567); // 产生:"123         4567"

3、也可以按照16进制打印:

sprintf(s, "%8x", 4567); // 小写16进制,宽度占8个位置,右对齐

sprintf(s, "%-8X", 4568); // 大写16进制,宽度占8个位置,左对齐

这样,一个整数的16进制字符串就很容易得到,但我们在打印16进制内容时,通常想要一种左边补0的等宽格式,那该怎么做呢?很简单,在表示宽度的数字前面加个0就可以了。

sprintf(s, "%08X", 4567); // 产生:"000011D7"

上面以 “%d” 进行的10进制打印同样也可以使用这种左边补0的方式。

sprintf 和 printf 还可以按8进制打印整数字符串,使用==“%o”==。注意8进制和16进制都不会打印出负数,都是无符号的,实际上也就是变量的内部编码的直接的16进制或8进制表示。

2、控制浮点数打印格式

浮点数的打印和格式控制是 sprintf 的又一大常用功能。

1、浮点数使用格式符“%f”控制,默认保留小数点后6位数字:

sprintf(s, "%f", 3.1415926); // 产生 "3.141593"

但有时我们希望自己控制打印的宽度和小数位数,这时就应该使用:“%m.nf”格式,其中m表示打印的宽度,n表示小数点后的位数。比如:

sprintf(s, "%10.3f", 3.1415626);    // 产生:"     3.142″

sprintf(s, "%-10.3f", 3.1415626);   // 产生:"3.142     "

sprintf(s, "%.3f", 3.1415626);      // 不指定总宽度,产生:"3.142"

附录:本文部分转载自sscanf函数使用详解sscanf的用法C 字符串函数 sprintf()、snprintf() 详解,感谢作者@faihung,@yanyanwenmeng,@love、reading。

以上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值