我使用printf函数有什么问题吗?

时间:2019-03-25 12:50:03

标签: c

已为我提供了以下任务以在C中执行:-

一年分为四个季节:春季,夏季,秋季和冬季。由于日历的构建方式,每年的确切日期会有所不同,但我们将使用以下日期进行这项练习:

第一天的季节
3月20日夏天
6月21日春季
9月22日秋天
12月21日冬季

创建一个程序,该程序从用户那里读取一个月和一天。用户将以字符串形式输入月份名称,然后以整数形式输入月份中的日期。

然后您的程序应显示与输入日期相关的季节。

注意:输入月份的前三个字母,例如:1月代表1月,2月代表2月,等等。...并且本月的第一个字母应为大写。

我编写了一个迷你测试代码来检查第一个条件,即3月20日。

这是我的代码:-

#include <stdio.h>
#include <string.h>

int main(int argc, const char * argv[]) {
int date;
char month[3];

printf("Enter the month\n");
scanf("%s",month);

printf("Enter the date\n");
scanf("%d",&date);

int temp;
temp= strcmp(month,"Mar");
printf("output is %d\n",temp);
return 0;
}

我得到的问题是,当输入为 Mar 20 时,我得到的是输出:-“输出为20” 。而我想在我的测试代码中将输出输出为0。

另一个观察结果是,如果我将日期更改为任意随机数,则将其作为输出,而我假设将得到存储在Temp中的值,即0。

如果我从代码中完全删除变量 date ,我将获得正确的输出。那时我的数字是0。

2 个答案:

答案 0 :(得分:4)

您使用printf函数是正确的,如https://linux.die.net/man/3/printf

所述,使用正确的转换说明符为其'%d'打印整数

变量“ month”可能不正确。 这是一个3字节的char缓冲区,用于存储。您正在使用它来存储以null终止的字符串,因此它只能存储2个ASCII字符+ null终止符。

另一个问题是如何使用scanf函数获取月份字符串。 如果您未指定字段宽度,则情况可能会变得很糟,请参见https://linux.die.net/man/3/scanf以获取更多信息。

答案 1 :(得分:0)

请记住,C字符串包含一个0值的终止符,因此要存储N个字符的字符串,您需要一个至少N + 1个元素宽的字符数组。

诸如strcmp之类的字符串管理功能依靠该终止符来告诉他们字符串的结尾在哪里。您得到奇怪输出的可能原因是字符串常量"Mar"以0终止,而存储在month数组中的字符串不是,所以strcmp读到末尾month数组中的值,直到它看到一个0值的字节并返回"Mar""Marx"之间的差,其中 x 表示未知字节序列。

访问数组末尾的内存将导致不确定的行为,并且可能出现任何结果。

要解决此特定问题,请将month声明为char的4元素数组,并在scanf调用中将输入限制为3个字符:

char month[4];
...
scanf( "%3s", month );

main的标准签名是

int main( void )

int main( int argc, char *argv[] ); // NOT const

argv数组应该是可修改的:

5.1.2.2.1程序启动
...
—参数 argc argv 以及由 argv 数组指向的字符串应 可由程序修改,并在程序之间保留其最后存储的值 启动和程序终止。

C 2011 Online Draft