【问题标题】:C mktime() printing issueC mktime() 打印问题
【发布时间】:2015-10-16 06:55:53
【问题描述】:

我正在开发按含义分隔字符的程序。目前我遇到了函数 konverzia 的问题。它应该在日期字符串中添加日期名称(星期三、星期四、星期五...),但它并不在乎。日期必须看起来像这样 Wed 2012-02-01 感谢您的任何想法。

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <time.h>

 void vstup (int i, char buffer[], int s, int c)
  {
        printf("\n Type text for analysis: \n ");    
        scanf ("%80s", buffer);      /* Read a string into buffer  */
  }
 void detekcia (int i, char buffer[], int s, int c, int z)
  {
         while(buffer[i] != '\0') {
            if(isalpha(buffer[i]))
                 s++;                /* Increment letter count     */
            if(isdigit(buffer[i++]))
                 c++;                /* Increment digit count      */
            if(ispunct(buffer[i++]))
                 z++;
                                  }
        if (s >= 1 && c >= 1)
          printf("\n word: %s \n", buffer);     /*kombinacia cisla a pismena*/
        if (s >= 1 && c == 0)
          printf("\n word: %s \n", buffer);     /*WORD*/
        if (s == 0 && c >= 1 && z == 0)
          prvocislo (i,buffer,s,c);             /*NUMBER*/
        if (s >= 0 && c >= 1 && z >= 1)
          datum (i,buffer,s,c,z);               /*DATE*/
 }
  int prvocislo (int i, char buffer[], int s, int c) /*prime number fun*/
  {
        int x,count=0;
        int k = atoi(buffer);

        for (x=2; x<=k/2;x++){
            if (k%x==0){
                count++;
                   break;
                }
        }
        if (count==0 && k!=1 && k!=0)
            printf("\n number: %d (prime)\n",k);
        else
            printf("\n number: %d",k);
  }
  int datum (int i, char buffer[], int s, int c, int z)
  {
        int q = 0;
        char d[2];
        char m[2];
        char r[4];

        if (buffer[4]=='-' && buffer[7]=='-')
           q++;                                                                                           
    if (q==1 && buffer[5]<='1')
           q++;
        if (q==2 && buffer[8]<='3')
           q++;
        if (q==3){
           q++;
           d[1]==buffer[9];
           d[0]==buffer[8];
           m[1]==buffer[6];
           m[0]==buffer[5];
           r[3]==buffer[3];
           r[2]==buffer[2];
           r[1]==buffer[1];
           r[0]==buffer[0];
                 }
        if (q==4)
           konverzia (d,m,r);
   }
   int konverzia (char d[], char m[], char r[])
  {
        int rr = atoi(r);
        int dd = atoi(d);
        int mm = atoi(m);
        int ret;
        struct tm info;
        char date[10];

        info.tm_year = rr - 1900;
        info.tm_mon = mm - 1;
        info.tm_mday = dd;
        info.tm_wday = dd;

        ret = mktime(&info);
        if (ret == -1){
        printf("time error");
                      }
        else{
           strftime(date, sizeof(date),"%c",&info);
           printf(date);
            }

        return(0);
  }
  int main() {

  char buffer[80];
  int i = 0;
  int s = 0; /*pismeno*/
  int c = 0; /*cislo*/
  int z = 0;
  vstup (i,buffer,s,c);
  detekcia (i,buffer,s,c,z);
  return 0;
  }

【问题讨论】:

  • "info.tm_wday" 为您提供周一、周四、...的 0-6 - 所以去谷歌寻找“switch/case”并解决它。
  • 十个字符甚至不足以打印像 2015-10-16 这样的常规数据,更不用说一个工作日。如果您想强制执行某种日期格式,您可以自己构建它,而不是依赖首选格式%c

标签: c mktime time.h


【解决方案1】:

如果你想要一个特定的格式,你必须构造一个自定义格式字符串。 documentation for strftime 中列出了可能的条目。您使用的 %c 格式只是您的语言环境的首选格式。

您的代码存在一些问题:

  • 您不应将tm_wday 设置为月份中的某天。 tm_wday 是工作日的索引,从 0 开始表示星期日。
  • 您应该将您的struct tm 初始化为零,这样您未分配的字段就不会有无意义的值。
  • 您的date 缓冲区太短。 strftime 防止溢出,但日期会被截断。
  • 不要直接使用printf 字符串,而是使用printf("%s", str)。特别是,格式字符串不应该是您无法控制的字符串。例如,strftime 中的未知% 序列可能不会被转换,并且在没有正确参数的情况下会被错误地解释为printf 格式。一些静态分析工具坚持只使用字符串文字作为格式字符串。我认为这是一种很好的做法。

所以:

int konverzia(const char d[], const char m[], const char r[])
{
    int rr = atoi(r);
    int dd = atoi(d);
    int mm = atoi(m);

    struct tm info = {0};

    info.tm_year = rr - 1900;
    info.tm_mon = mm - 1;
    info.tm_mday = dd;

    if (mktime(&info) == -1) {
        printf("time error\n");
        return -1;
    } else {
        char date[20];

        strftime(date, sizeof(date), "%a %Y-%m-%d", &info);
        printf("%s\n", date);
    }

    return 0;
}

【讨论】:

  • 非常感谢您的宝贵时间,我非常感谢您的帮助,但请查看它对 output:::::::..... 的作用:键入文本进行分析:2001-11- 11 Tue -1-11-30:.................. 输入哪个输入都没有关系,它总是给出这个 Tue日期
  • 我在konverzia 函数之外没有看太多你的程序,我已经用几个日期明确地测试了它,比如konverzia("16", "10", "2015"); 我建议你检查你传入的字符串。做再进行几次测试,我看到mktime“规范化”了错误的输入,因此 6 月 31 日实际上是 7 月 1 日。这意味着您应该添加额外的有效性检查,而不是依赖 mktime 返回 -1。
  • 非常感谢!最后我发现了错误,现在效果很好:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-16
  • 1970-01-01
  • 2017-04-23
  • 2016-10-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多