【问题标题】:Is there any problem with my usage of printf function?我使用 printf 函数有什么问题吗?
【发布时间】:2019-08-15 17:15:35
【问题描述】:

我被赋予了在 C 中执行以下任务:-

一年分为春、夏、秋、冬四个季节。虽然由于日历的构造方式,季节变化的确切日期每年都会略有不同,但我们将在本练习中使用以下日期:

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

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

那么你的程序应该显示与输入日期相关的季节。

注意:输入月份的前三个字母,例如:Jan 代表一月,Feb 代表二月,依此类推......并且月份的第一个字母应该是大写。

我写了一个小测试代码来检查第一个条件,即Mar 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;
}

我遇到的问题是,在输入 Mar20 时,我得到了输出:- "output is 20"。而我想在我的测试代码中输出为 0。

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

如果我从代码中完全删除变量 date,我会得到正确的输出。那时我得到 0。

【问题讨论】:

  • Const char *argv[]??这不是一个有效的参数!
  • char month[3] 只能存储 2 个字符,因为第三个字符是 \0
  • month 有 3 个字符的空间。 “Jan”需要 4 个字符的空间!你不能把 4 匹马放在 3 个马厩里!
  • 目前在 Xcode 上编码。默认情况下,它具有以下参数: -*argv[]
  • @machine_1:将const 添加到第二个参数不会使其无效。

标签: c


【解决方案1】:

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

strcmp 这样的字符串管理函数依赖于该终止符来告诉他们字符串的结尾在哪里。您得到奇怪输出的可能原因是字符串常量 "Mar" 是以 0 结尾的,而存储在您的 month 数组中的字符串不是,所以 strcmp 正在读取超过 month 数组的末尾直到它看到一个 0 值字节并返回 "Mar""Mar<em>x</em>" 之间的差异,其中 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 程序启动
...
argcargv 参数以及 argv 数组所指向的字符串应 可由程序修改,并在程序之间保留它们最后存储的值 启动和程序终止。

C 2011 Online Draft

【讨论】:

    【解决方案2】:

    您的 printf 函数的使用是正确的,您使用正确的转换说明符为它打印一个整数 '%d',如 https://linux.die.net/man/3/printf 中所述

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-13
      • 1970-01-01
      • 1970-01-01
      • 2021-04-11
      • 2015-09-30
      • 2017-10-07
      相关资源
      最近更新 更多