Entonces, básicamente, necesito encontrar una manera de hacer que el mes de mi fecha se convierta en número, así como mi tiempo para pasar del horario militar al horario estándar. Tengo problemas para ejecutar mi código y no puedo entender por qué. Probablemente sea un simple error, pero si se dan cuenta, háganmelo saber.

from Monday, June 2, 2012, 22:12:12 to 6/2/2012, 10:12 PM format. 
#include <stdio.h>
#include <string.h>

/*This code will take user input of date and use 2-d array to store strings
 using delimeter as well. It will list all
 the date in descending order seperating:
   "Month", "Day", "Year", "Hour", "Minute", "Second"
   from:
   "Saturday, July 8, 2017, 22:14:10"
*/

int findMonthNum(const char *key);

int main(void){


    char *check[] = {
            "Saturday", "Monday", "Tuesday", "Wednesday", "Thursday",
            "Sunday", "Friday",
#if 1
            NULL
#endif
    };

    char *monthString[] = {
            "January", "February", "March", "April", "May", "June", "July", "August", "September",
            "October", "November", "December",
#if 1
            NULL
#endif
    };

    char **day;
    char **month;


    // creates 2 day array
    char date[8][20];

    // creates order of time
    char *order[] = { "Month", "Day", "Year", "Hour", "Minute", "Second" };

    printf("Enter date separated by commas in following format:\n");
    printf(" Example: Saturday, July 8, 2017, 22:14:10\n");

    // array to store string initially
    char text[64];

    // reads strings
    fgets(text, 64, stdin);

    // this is the delimeter that will be helpful for seperating it to
    // different tokens
    char *delims = " ,:";
    char *token = strtok(text, delims);
    char **label = order;
    int r = 0;

    while (token) {
        // look for match on day of the week
        for (day = check;  *day != NULL;  ++day) {
            if (strcmp(token,*day) == 0)
                break;
        }

        // if _not_ day of the week, store the value
        if (*day == NULL) {
            strcpy(date[r], token);

            printf("%-8s: %s\n ", *label, date[r]);

            label++;
            r++;
        }

        // this is so that it will find null values at the end and leave off
        // where it was.
        token = strtok(NULL, delims);


    }
    // Convert the above date to 7/8/2017, 10:14 PM format
     int findMonthNum(const char *key){
        static const char *monthStrings[] = {
                "January", "February", "March", "April", "May", "June", "July", "August", "September",
                "October", "November", "December", NULL
        };

        for( int i = 0; monthStrings[i] != NULL; i++ ) {
            if( strcmp(monthStrings[i], key) == 0 ) {
                return i+1;
            }
        }

        return -1;

    }


        printf("%d/%s/%s, %s:%s", findMonthNum(date[0]), date[1], date[2], date[4], date[5]);




    return 0;
}

Sigue diciendo la expresión esperada antes de los concursos.

0
user3117455 22 jun. 2020 a las 22:37

3 respuestas

La mejor respuesta

Puede iterar a través de monthString hasta que coincida, luego devolver el índice + 1 o -1 si no se encuentra.

int findMonthNum(const char *key) {
    // This is declared `static` so it's only ever allocated once.
    //
    // It's declared inside the function so long as the function is
    // the only thing using it.
    //
    // It's declared `const char *monthStrings[]` because
    // it is an array of `const char *`. "Strings like this" are
    // constants and cannot be modified.
    //
    // The NULL at the end lets us known when to stop iterating
    // without knowing the length of the array.
    static const char *monthStrings[] = {
        "January", "February", "March", "April", "May", "June", "July", "August", "September",
        "October", "November", "December", NULL
    };

    // Iterate from monthStrings[0] until you hit a NULL value.
    for( int i = 0; monthStrings[i] != NULL; i++ ) {
        if( strcmp(monthStrings[i], key) == 0 ) {
            return i+1;
        }
    }

    // Return -1 if you don't find a matching month.
    return -1;
}

int monthNum = findMonthNum("June"); // 6
monthNum = findMonthNum("Septembuary"); // -1

Sin embargo, C ha incorporado funciones strptime para analizar fechas y horas y strftime para formatearlos. Ambos usan la misma especificación de tipo sprintf para analizar y formatear.

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

int main()
{
    char date[] = "Monday, June 2, 2012, 22:12:12";
    struct tm parsed;

    // Parse the string into a struct tm.
    strptime(date, "%A, %B %e, %Y, %T", &parsed);

    // Print it to check it parsed correctly.
    printf("parsed: %s\n", asctime(&parsed));

    // Format the struct tm to a new string.
    char formatted[40];
    strftime(
        formatted,
        sizeof(formatted), 
        "%D %I:%M %p",
        &parsed
    );
    printf("formatted: %s\n", formatted);
}
0
Schwern 22 jun. 2020 a las 20:38

Aquí lo tiene sin ninguna función stdlib.

#include <stdio.h>
#include <stdint.h>

typedef struct
{
    int year, month, day;
    int hour, min, sec;
    int am;
}mytime_t;

unsigned mystrtou(const char *str)
{
    unsigned result = 0;
    while(*str)
    {
        result *= 10;
        result += *str++ - '0';
    }
    return result;
}

char *skipspaces(char *str)
{
    while(*str && (*str == ' ' || *str == ',')) str++;
    return str;
}

int streq(const char *str1, const char *str2)
{
    int result = 0;
    while(*str1 || *str2)
    {
        if(*str1++ != *str2++)
        {
            result = 1;
            break;
        }

    }
    return result;
}

int slice(char *mil, char **argv)
{
    int argc = 0;

    mil = skipspaces(mil);
    if(*mil)
    {
        argc++;
        *argv = mil;
        argv++;
    }
    while(*mil)
    {
        if(*mil == ',' || *mil == ' ' || *mil == ':')
        {
            *mil++ = 0;
            mil = skipspaces(mil);
            if(*mil)
            {
                argc++;
                *argv = mil;
                argv++;
            }
        }
        mil++;
    }
    return argc;
}

const char *monthNames[] = {
        "January", "February", "March", "April", "May", "June", "July", "August", "September",
        "October", "November", "December",
};

int getMonth(const char *month)
{
    int result = -1;
    for(int index = 0; index < sizeof(monthNames) / sizeof(monthNames[0]); index++)
    {
        if(!streq(month, monthNames[index]))
        {
            result = index + 1;
            break;
        }
    }
    return result;
}

int convert(char *data, mytime_t *time)
{
    int result = -1;
    char *argv[10];
    int argc = slice(data, argv);

    if(argc == 7)
    {
        result = 0;
        time -> am = 1;
        time -> year = mystrtou(argv[3]);
        time -> month = getMonth(argv[1]);
        time -> day = mystrtou(argv[2]);

        time -> hour = mystrtou(argv[4]);
        time -> min = mystrtou(argv[5]);
        time -> sec = mystrtou(argv[6]);
        if(time -> hour > 12)
        {
            time -> am = 0;
            time -> hour -= 12; 
        }
    }
    return result;
}

int main()
{
    char str[] = "Monday, June 2, 2012, 22:12:12";

    mytime_t time;

    convert(str, &time);
    

    printf("%d/%d/%d %d:%d %s\n", time.month, time.day, time.year, time.hour, time.min,  time.am ? "am" : "pm");
}

https://godbolt.org/z/qSFh8p

0
P__J__ 23 jun. 2020 a las 00:23

Alternativa a verificar el nombre hasta 12 veces

Al asignar un nombre de mes a un índice, podemos divertirnos un poco.

Supongamos que los nombres de los meses permanecen como están en inglés. Observe que los caracteres segundo y tercero son suficientes para distinguir los 12.

Hash agregando esos 2 caracteres y mira los 5 LSbits para formar un índice en un mapa. Compare si el valor mapeado coincide. Muy rápido: solo 1 cadena de comparación.

Por supuesto, esto no es directamente aplicable si el código usa un conjunto diferente en los nombres de los meses.

#include <ctype.h>
#include <string.h>

static const char *monthString[] = { //
    "January", "February", "March", "April", //
    "May", "June", "July", "August", //
    "September", "October", "November", "December" };

int month_to_index(const char *month_name) {
  size_t len = strlen(month_name);
  if (len >= 3) {
    unsigned sum = (tolower(month_name[1]) + tolower(month_name[2])) %32;
    static const unsigned char table[32] = {
        [1] = 7, [2] = 4, [3] = 6, [5] = 11, //
        [7] = 2, [8] = 12, [15] = 1, [19] = 3, //
        [21] = 9, [23] = 10, [26] = 5, [28] = 8 //
    };
    unsigned index = table[sum];
    if (index && strncasecmp(month_name, monthString[index-1], len) == 0) {
      return index;
    }
  }
  return 0;
}

Uso de la muestra

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

int main() {
  for (int mm = 0; mm<12; mm++) {
    char buf[20];
    strcpy(buf, monthString[mm]);
    int len = strlen(buf);
    if (len > 3) {
      int offset = rand() % (len-3) + 3;
      buf[offset] = '\0';
    }
    for (int i=0; buf[i]; i++) {
      if (rand()%2) {
        buf[i] ^= 'A' ^ 'a'; // toggle case
      }
    }
    unsigned index = month_to_index(monthString[mm]);
    if (index > 0) {
      printf("%2i %2u <%10s> <%s>\n", mm, index, monthString[mm], buf);
    }
  }
  return 0;
}

Salida

 0  1 <   January> <jaNu>
 1  2 <  February> <FebRUA>
 2  3 <     March> <maRc>
 3  4 <     April> <apR>
 4  5 <       May> <may>
 5  6 <      June> <jUn>
 6  7 <      July> <jUL>
 7  8 <    August> <AUgu>
 8  9 < September> <SePTe>
 9 10 <   October> <OCT>
10 11 <  November> <nOvem>
11 12 <  December> <deC>
0
chux - Reinstate Monica 22 jun. 2020 a las 22:20