简体   繁体   English

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

[英]Is there any problem with my usage of printf function?

I have been given the following task to perform in C: - 我被赋予以下任务以在C中执行:-

The year is divided into four seasons: spring, summer, fall and winter. 一年分为四个季节:春季,夏季,秋季和冬季。 While the exact dates that the seasons change vary a little bit from year to year because of the way that the calendar is constructed, we will use the following dates for this exercise: 尽管由于日历的构建方式,每年的确切日期会有所不同,但在本练习中,我们将使用以下日期:

Season First day 季节第一天
Summer March 20 3月20日夏季
Spring June 21 6月21日春季
Fall September 22 9月22日秋季
Winter December 21 12月21日冬季

Create a program that reads a month and day from the user. 创建一个程序,从用户读取一个月和一天。 The user will enter the name of the month as a string, followed by the day within the month as an integer. 用户将以字符串形式输入月份名称,然后以整数形式输入月份中的日期。

Then your program should display the season associated with the date that was entered. 然后,程序应显示与输入日期关联的季节。

Note: Enter First three letter for month example: Jan for january, Feb for Feburary ans so on....and first letter of the month should be capital. 注意:例如,输入月份的前三个字母:1月代表1月,2月代表2月,等等。。。。。。。。。。。。。。。。。

I wrote a mini test code to check the first condition, that is Mar 20. 我编写了一个迷你测试代码来检查第一个条件,即3月20日。

Here is my code: - 这是我的代码:-

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

The problem which I am getting is that while giving input as Mar and 20 , I am getting output: - "output is 20" . 我得到的问题是当输入为Mar20时 ,我得到输出:- “ output is 20” Whereas i am suppose to get output as 0 in my test code. 而我想在我的测试代码中将输出设为0。

One more observation is that if I change the date to any random number, I am getting that as the output, whereas i am suppose to get the value which is stored in Temp, ie 0. 另一个观察结果是,如果我将日期更改为任何随机数,则将其作为输出,而我假设将得到存储在Temp中的值,即0。

I am getting correct output if i remove variable date completely from the code. 如果我从代码中完全删除可变日期,我将获得正确的输出。 At that time I am getting 0. 那时我得到0。

The use of your printf function is correct, your printing an integer using the correct conversion specifier for it '%d', as documented on https://linux.die.net/man/3/printf 您使用的printf函数是正确的,您使用正确的转换说明符'%d'来打印整数,如https://linux.die.net/man/3/printf所述

What may not be fine is the variable 'month'. 变量“ month”可能不是很好 It is a char buffer with 3 bytes for storage. 这是一个3字节的char缓冲区,用于存储。 You are using it to stored null terminated strings, so it can only store 2 ASCII characters + the null terminator. 您正在使用它来存储以null终止的字符串,因此它只能存储2个ASCII字符+ null终止符。

Another concern is how the scanf function is used for getting the month string. 另一个问题是scanf函数如何用于获取月份字符串。 If you do not specify a field width, things can get ugly, see https://linux.die.net/man/3/scanf for further info. 如果未指定字段宽度,则情况可能会变得很丑陋,有关更多信息,请参见https://linux.die.net/man/3/scanf

Remember that C strings include a 0-valued terminator, so to store an N-character string, you need a character array that's at least N+1 elements wide. 请记住,C字符串包含一个0值的终止符,因此要存储N个字符的字符串,您需要一个至少N + 1个元素宽的字符数组。

String management functions like strcmp rely on that terminator to tell them where the end of the string is. strcmp这样的字符串管理功能都依赖于该终止符来告诉他们字符串的结尾在哪里。 The likely reason you're getting weird output is that the string constant "Mar" is 0-terminated, while the string stored in your month array is not, so strcmp is reading past the end of the month array until it sees a 0-valued byte and is returning the difference between "Mar" and "Mar x " , where x represents some unknown sequence of bytes. 您得到怪异输出的可能原因是字符串常量"Mar"以0结尾,而存储在month数组中的字符串却不是,所以strcmp读到month数组的末尾直到看到0-值字节,并返回"Mar""Mar x "之间的差,其中x表示一些未知的字节序列。

Accessing memory past the end of an array results in undefined behavior , and any result is possible. 访问数组末尾的内存将导致未定义的行为 ,并且任何结果都是可能的。

To fix this particular issue, declare month as a 4-element array of char and limit the input to 3 characters on the scanf call: 要解决此特定问题,请将month声明为4个元素的char数组,并在scanf调用中将输入限制为3个字符:

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

The standard signature of main is either main的标准签名是

int main( void )

or 要么

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

The argv array is supposed to be modifiable: argv数组应该是可修改的:

5.1.2.2.1 Program startup 5.1.2.2.1程序启动
... ...
— The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination. —参数argcargv以及argv数组指向的字符串应可由程序修改,并在程序启动和程序终止之间保留其最后存储的值。

C 2011 Online Draft C 2011在线草案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM