Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> очень красивая функция с помощью профессионалов 
:(
    Опции темы
segadir
Дата 7.9.2010, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 7.9.2010

Репутация: нет
Всего: нет



написал простенькую функцию на Си
Код

/*-------------------------------------------------------------------------.
|                                                                           |
|    GetDate() - returns the current time in format fnowdate[]               |
|                            return global array nowdate[]                   |
|    fomat_date: man strftime                                               |
|                                                                           |
`-------------------------------------------------------------------------*/
void GetDate(void){
    struct tm tdat;
    long ltime;
    time(&ltime);
    tdat=*localtime(&ltime);
    strftime (nowdate,strlen(nowdate),fnowdate,&tdat);
}
, хотел бы с помощью профи на этом форуме, довести её до совершенства.
а именно:
Как вы уже заметили я использую глобальные массивы, что не есть гуд! 
Вот бы переделать её так что бы она стала указателем на результат, т.е.
Код

printf("Date:%s",GetDate("YYYY-MM-DD"));
printf("Time:%s",GetDate("hh-mm-ss"));
printf("sec:%s",GetDate("ss"));

эта функция очень маленькая, поэтому прошу !проффи! , мне очень хочеться посмотреть как можно до совершенства решить такую задачку.
спасибо.
PM MAIL   Вверх
djamshud
Дата 7.9.2010, 16:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 4
Всего: 39



Непрофессионал делает так:

Код

//lib
static char __stinternal_tbuf[128];

#define frm_date(format)({ \
time_t tm=time(0); \
strftime(__stinternal_tbuf,sizeof(__stinternal_tbuf),format,localtime(&tm)); \
__stinternal_tbuf;})

...

//src
int main(){
printf("%s\n",frm_date("%a %b %d %T %Y"));
return 0;}

Код

Tue Sep 07 17:10:37 2010


Сейчас вам еще покажут плюсовый пример на каком-нибудь boost-е.

Добавлено через 2 минуты и 51 секунду
Хм. Это этот дефайн легко превращается в обычную функцию. Изначально он был сложнее - буфер передавался как один из параметров дефайна, поэтому функция не подходила - sizeof(buf) не работал как задумано.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
segadir
Дата 7.9.2010, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 7.9.2010

Репутация: нет
Всего: нет



можно обойтись без задания конкретной длины 128? ведь формат может быть по длинее. ну вообще довольно таки здорово! Спасибо!
allprofi Будут ли еще варианты?

Это сообщение отредактировал(а) segadir - 7.9.2010, 16:26
PM MAIL   Вверх
djamshud
Дата 7.9.2010, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 4
Всего: 39



Код

#define frm_date(tbuf,format)({ \
time_t tm=time(0); \
strftime(tbuf,sizeof(tbuf),format,localtime(&tm)); \
tbuf;})


Вот раскопал оригинальный дефайн. Первым параметром передается заранее приготовленный буфер нужной длины. Но я от этого варианта отказался, потому что на деле 128 байт хватает с головой, а громоздкость кода значительно уменьшается.

Пожалуйста!


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
boostcoder
Дата 7.9.2010, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 20
Всего: 110



djamshud, глобальный буффер... smile сделайте его либо локальным, либо добавьте глобальный мьютекс.

Цитата(djamshud @  7.9.2010,  16:16 Найти цитируемый пост)
Сейчас вам еще покажут плюсовый пример на каком-нибудь boost-е.

именно. благо что говорится про Си. ибо в с++ нельзя использовать strftime().
единственный абсолютно правильный вариант - boost.format

PM WWW   Вверх
segadir
Дата 7.9.2010, 17:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 7.9.2010

Репутация: нет
Всего: нет



очень хотел бы услышать про то как можно отказаться от фиксированной (128)  длины массива, 
т.е. длина сама бы задавалась в зависимости от входной строки.
как вариант сделать - динамическим
но может есть что либо так сказать "по изящнее" ? а?
Код

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

char *getdate(char *format){
    static char buff[128];
    time_t tm=time(0);
    strftime(buff, sizeof(buff), format, localtime(&tm));
    return buff;
}

void main(){
    printf("%s\n",getdate("%Y/%m/%d %H:%M:%S"));
}

PM MAIL   Вверх
borisbn
Дата 7.9.2010, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



IMHO функция по-любому лучше.
1. Можно сделать параметр форматирования по-умолчанию, например "dd.MM.yyyy hh:mm:ss"
2. Можно вернуть std::string
3. Буфер можно выделить на стеке

и зачем в конце делается 
Цитата(djamshud @  7.9.2010,  16:30 Найти цитируемый пост)
tbuf;})

?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Sartorius
Дата 7.9.2010, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1568
Регистрация: 18.7.2006
Где: Ivory tower

Репутация: 2
Всего: 37



Цитата(boostcoder @  7.9.2010,  18:44 Найти цитируемый пост)
ибо в с++ нельзя использовать strftime().
  smile Это почему?

PM MAIL ICQ   Вверх
segadir
Дата 7.9.2010, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 7.9.2010

Репутация: нет
Всего: нет



Цитата(borisbn @ 7.9.2010,  17:58)
2. Можно вернуть std::string
3. Буфер можно выделить на стеке

да но я думаю это спарведливо только к С++??? или нет?
PM MAIL   Вверх
borisbn
Дата 7.9.2010, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(segadir @  7.9.2010,  18:04 Найти цитируемый пост)
да но я думаю это спарведливо только к С++??? или нет?

только 
Цитата(borisbn @  7.9.2010,  17:58 Найти цитируемый пост)
2. Можно вернуть std::string

а выделить память на стеке можно и в Си.
Правда в данном случае от неё толку не будет, потому, что вернуть char * на такую память нельзя
вернее можно, но получишь краш :(

кстати, твоё замечание нужно адресоватьи boost'овцам

Это сообщение отредактировал(а) borisbn - 7.9.2010, 18:10


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
icecrashldr
Дата 7.9.2010, 19:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Developer
*


Профиль
Группа: Участник
Сообщений: 122
Регистрация: 5.7.2010

Репутация: нет
Всего: нет



Мне опять скучно ... 

1) Локальный буфер

Код

static char __stinternal_tbuf[128];
#define frm_date(format) { \
time_t tm=time(0); \
strftime(__stinternal_tbuf,sizeof(__stinternal_tbuf),format,localtime(&tm)); \
__stinternal_tbuf;}


Оформляем
Код

#define frm_date(format) { \
static char __stinternal_tbuf[128];
time_t tm=time(0); \
strftime(__stinternal_tbuf,sizeof(__stinternal_tbuf),format,localtime(&tm)); \
__stinternal_tbuf;}


Буфер будет локальным, и в пределах блока который был в дефайне, и "драки" имен между переменными быть не должно.

2) Глобальный буфер
Выше описанный спсоб будет работать, вот только в много поточном приложении будет плохо так что либо синхронизация(Mutex, CriticalSction) или
переменная нити(потока) __declspec(thread) для студии.


Sartorius, Можно, но только это микс С с С++, не которые личность утверждают что это от лукавого, но каждому свое.


borisbn
Цитата

вернее можно, но получишь краш :(

Креш не получи, так как память валидная, а вот гарантировать валидность данных, это не получится, так как при "закрутки" стека компилятор волен выбирать метод самостоятельно, так что это вы правы использовать НЕЛЬЗЯ.

PM MAIL WWW   Вверх
djamshud
Дата 8.9.2010, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 4
Всего: 39



boostcoder, во-первых, не каждое приложение многопоточно; во-вторых, многопоточность - костыль; в-третьих, буфер локален в пределах одного объектного файла. Но вообще, да :).

borisbn,

>и зачем в конце делается 

Чтобы "вернуть" указатель из макроса. См., как раскрывается макрос в код.

icecrashldr, 

>локальный буфер

В общем да, только я его немного пропатчу для ТС:) "({})" - GCC-шное расширение, но без него никак: обычный #define macro{...} раскроется в код и все испортит, #define macro ... и нормальной "локальной" tm не сделает, и код попортит.

segadir,

Код

//macro
#define frm_date(format,size)({ \
time_t tm=time(0); \
char tbuf[size]; \
memset(tbuf,0,sizeof(tbuf)); \
strftime(tbuf,sizeof(tbuf),format,localtime(&tm)); \
tbuf;})

//func
char const *frm_date(char const *format,size_t len){
static char *buf=0;
free(buf);
buf=malloc(len);
memset(buf,0,len);
time_t tm=time(0);
strftime(buf,len,format,localtime(&tm));
return buf;}


Но обнаружился неприятный баг strftime-а: если сформированная им строка-дата не влезает в отведенный буфер, функция мало того, что не выставляет \0 в его конец, так еще и возвращает неправильный return value. В приведенных примерах я это пофиксил, но думается мне, надо писать багрепорт в ГНУ, т.к. в мане про этот баг ни слова не нашел.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
azesmcar
Дата 8.9.2010, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата(djamshud @  8.9.2010,  10:56 Найти цитируемый пост)
во-вторых, многопоточность - костыль

это еще почему? smile 
PM   Вверх
djamshud
Дата 8.9.2010, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 4
Всего: 39



azesmcar, потому что рулит многопроцессность либо изначальное затачивание программы для многопоточного (десятки и сотни нитей) решения чего-нибудь на кластере. В обоих случаях это отдельно оговаривается и соответствующим образом проектируется все приложение, и обозначенной проблемы не будет. В этом топике я холиворить больше не будуsmile.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
azesmcar
Дата 8.9.2010, 11:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата(djamshud @  8.9.2010,  11:12 Найти цитируемый пост)
В обоих случаях это отдельно оговаривается и соответствующим образом проектируется все приложение

 smile 

Цитата(djamshud @  8.9.2010,  11:12 Найти цитируемый пост)
и обозначенной проблемы не будет

а..это вы в контексте обозначенной проблемы? я думал вообще, так сказать глобально smile 
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0832 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.