Проблема с печатью C mktime()

Я работаю над программой, которая разделяет символы по значению. В настоящее время у меня проблема с функцией konverzia. Он должен добавить название дня (ср, чт, пт...) к строке даты, но ему насрать. Дата должна выглядеть так: среда 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;
  }

person MrBr    schedule 16.10.2015    source источник
comment
info.tm_wday дает вам 0-6 для понедельника, четверга, ... - так что зайдите в Google, найдите переключатель/регистр и решите его.   -  person EGOrecords    schedule 16.10.2015
comment
Десяти символов недостаточно даже для вывода обычных данных, таких как 2015-10-16, не говоря уже о днях недели. Если вы хотите применить определенный формат даты, вы можете создать его самостоятельно, вместо того, чтобы полагаться на предпочтительный формат %c.   -  person M Oehm    schedule 16.10.2015


Ответы (1)


Если вам нужен определенный формат, вы должны создать строку пользовательского формата. Возможные записи перечислены в документации для strftime. Формат %c, который вы используете, является предпочтительным форматом для вашей локали.

Есть некоторые проблемы с вашим кодом:

  • Вы не должны устанавливать tm_wday на день месяца. tm_wday — это индекс дня недели, начиная с 0 для воскресенья.
  • Вы должны инициализировать struct tm нулем, чтобы поля, которые вы не назначаете, не имели бессмысленных значений.
  • Ваш буфер date слишком короткий. strftime защищает от переполнения, но дата будет усечена.
  • Не используйте строки printf напрямую, вместо этого используйте printf("%s", str). В частности, строка формата не должна быть строкой, которой вы не управляете. Например, неизвестная последовательность % в strftime может не преобразоваться и будет ошибочно интерпретирована как формат printf без правильного аргумента. Некоторые инструменты статического анализа настаивают на использовании только строковых литералов в качестве строк формата. Хорошая практика, я считаю.

So:

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;
}
person M Oehm    schedule 16.10.2015
comment
Большое спасибо за ваше время, я очень ценю вашу помощь, но посмотрите, что она сделала для вывода:::::::..... Введите текст для анализа: 2001-11-11 Вт -1- 11-30:................... и не имеет значения, какой ввод я ввожу, он всегда дает эту дату вторника - person MrBr; 16.10.2015
comment
Я мало смотрел на вашу программу за пределами функции konverzia, и я протестировал ее явно с несколькими датами, например konverzia("16", "10", "2015");. Я предлагаю вам проверить строки, которые вы передаете. Проведя еще несколько тестов, я вижу, что mktime нормализует неверный ввод. , так что 31 июня на самом деле 1 июля. Это означает, что вы должны добавить дополнительные проверки на достоверность вместо того, чтобы полагаться на то, что mktime возвращает -1. - person M Oehm; 16.10.2015
comment
Большое спасибо! наконец я нашел ошибку, и теперь она отлично работает :) - person MrBr; 19.10.2015