Обращение к структуре в цикле ?
От: DrunkPilot  
Дата: 07.02.13 23:02
Оценка: -1
Есть у меня структурка такого вида .

struct userdata {
    wchar_t * login;
    wchar_t * passwd;
    wchar_t * balance;
    wchar_t * email;
    wchar_t * phone;
        и тд...
};

Храню в ней данные от парсера . Числом более 10 , а может уже и 15 эл-тов .
Хотелось бы сделать обращение к ней через цикл . Потому что иначе приходится обрабатывать каждую строку по-очереди : например выделять память , перекодировать строки в wchar и тд . И это выглядит как-то совсем криво , даже для новичка .
Почему-то никакое нормальное решение уже несколько дней не приходит .
Re: Обращение к структуре в цикле ?
От: __kot2  
Дата: 08.02.13 01:24
Оценка: +1
какой-то камменоугольного века код

это если С++, то для начала я бы заменил wchar_t на string

если прямо сильно хочется иметь доступ к элементам и по имени и по очереди, то можно их запихать все в std::map

ну и в принципе можно сделать трюк заведя массивчик указателей и перенацелив указатели на индексы этого массивчика. но это сделает код еще отстойнее.
Re[2]: Обращение к структуре в цикле ?
От: sgenie  
Дата: 08.02.13 01:58
Оценка: -2
Ну почему? Если вся структура такая, то можно (зная выравнивание) просто взять адрес первои строки и перемещаться на следующую просто добавление размера указателя.
Re[3]: Обращение к структуре в цикле ?
От: __kot2  
Дата: 08.02.13 02:13
Оценка: 6 (1) +1
Здравствуйте, sgenie, Вы писали:
S>Ну почему? Если вся структура такая, то можно (зная выравнивание) просто взять адрес первои строки и перемещаться на следующую просто добавление размера указателя.
неужели проблем так мало, что обязательно хочется их потенциальное кол-во увеличить?
— кто-нить может эту стуктуру переименовать в класс, сделать пару виртуальных методов и внезапно все сломается
— кто-нить может вбить между сточками свое поле. или вначало его воткнуть? почему бы нет?
— Вася захардкодит переход к след указателю через 4 байта, а Петя потом соберет под x64 и будет долго ругаться с Васей
— какая-нить опция компиляции вдруг внезапно захочет вставить пробел между полями или какая-нить оптимизация вообще поля перетусует. чего бы нет-то?
— кто-нить через несколько лет начнет переписывать на C# и прифигеет от каких-то странных смещений и прыжках по памяти в бизнес-логике, сотрет все нафиг и перепишет, где-нить обязательно накосячив
Re: Обращение к структуре в цикле ?
От: johny5 Новая Зеландия
Дата: 08.02.13 02:15
Оценка: 6 (1)
Здравствуйте, DrunkPilot, Вы писали:

DP>Есть у меня структурка такого вида .


DP>
DP>struct userdata {
DP>    wchar_t * login;
DP>    wchar_t * passwd;
DP>    wchar_t * balance;
DP>    wchar_t * email;
DP>    wchar_t * phone;
DP>        и тд...
DP>};
DP>

DP>Храню в ней данные от парсера . Числом более 10 , а может уже и 15 эл-тов .
DP>Хотелось бы сделать обращение к ней через цикл . Потому что иначе приходится обрабатывать каждую строку по-очереди : например выделять память , перекодировать строки в wchar и тд . И это выглядит как-то совсем криво , даже для новичка .
DP>Почему-то никакое нормальное решение уже несколько дней не приходит .

enum
{
    login,
    passwd,
    balance,
    email,
    phone,
    и тд...,
    last
};

wstring  data[last];

for each(wstring& in data)...


Кул?
Re: Обращение к структуре в цикле ?
От: Nikita.Trophimov  
Дата: 08.02.13 04:10
Оценка: 7 (2)
#include <cstring>
#include <iostream>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/for_each.hpp>

struct userdata
{
   wchar_t* login;
    wchar_t* passwd;
    wchar_t* balance;
    wchar_t* email;
    wchar_t* phone;
};

BOOST_FUSION_ADAPT_STRUCT(
    userdata,
    (wchar_t*, login)
    (wchar_t*, passwd)
    (wchar_t*, balance)
    (wchar_t*, email)
    (wchar_t*, phone)
    )

struct Foo
{
    template <typename T>
    void operator()(T& bar) const
    {
        bar = new wchar_t[256];
        wcscpy(bar, L"Some Data");
    }
};

int main()
{
    userdata instance;
    boost::fusion::for_each(instance, Foo());

    std::wcout << instance.login << '\n'
            << instance.passwd << '\n'
            << instance.balance << '\n'
            << instance.email << '\n'
            << instance.phone << '\n';
}


Или сразу так, если это Ваша структура, и Вы можете модифицировать её определение:

#include <cstring>
#include <iostream>
#include <boost/fusion/include/define_struct.hpp>
#include <boost/fusion/include/for_each.hpp>

BOOST_FUSION_DEFINE_STRUCT(
    (), userdata,
    (wchar_t*, login)
    (wchar_t*, passwd)
    (wchar_t*, balance)
    (wchar_t*, email)
    (wchar_t*, phone)
    )

struct Foo
{
    template <typename T>
    void operator()(T& bar) const
    {
        bar = new wchar_t[256];
        wcscpy(bar, L"Some Data");
    }
};

int main()
{
    userdata instance;
    boost::fusion::for_each(instance, Foo());

    std::wcout << instance.login << '\n'
            << instance.passwd << '\n'
            << instance.balance << '\n'
            << instance.email << '\n'
            << instance.phone << '\n';
}


Кстати, зачем Вам понадобились wchar_t*, а не std::wstring, например?
Re[2]: visitor без буст
От: johny5 Новая Зеландия
Дата: 08.02.13 07:09
Оценка: 12 (2)
Здравствуйте, Nikita.Trophimov, Вы писали:

И тоже самое без буста:

struct userdata {
    wchar_t * login;
    wchar_t * passwd;
    wchar_t * balance;
    wchar_t * email;
    wchar_t * phone;
    
    template<typename V> void visit(V& visitor)
    {
        v(login);
        v(passwd);
        v(balance);
        v(email);
        v(phone);
    }
};

userdata instance;
instance.visit( Foo() );
Re[2]: Обращение к структуре в цикле ?
От: jyuyjiyuijyu  
Дата: 08.02.13 08:28
Оценка:
Здравствуйте, Nikita.Trophimov, Вы писали:

это какая то магия )
Re[4]: Обращение к структуре в цикле ?
От: Mr.Delphist  
Дата: 08.02.13 08:37
Оценка: :)
Здравствуйте, __kot2, Вы писали:

__>- Вася захардкодит переход к след указателю через 4 байта, а Петя потом соберет под x64 и будет долго ругаться с Васей


Даже в Delphi есть адресная арфиметика, так что обычного ++ там будет достаточно. Нет, ну я понимаю, что настоящий си-гуру сначала всё кастует к void*, но от тогда также заведет макрос для величины инкремента, чтобы autotools нормально отрабатывали на разных платформах
Re[2]: Обращение к структуре в цикле ?
От: DrunkPilot  
Дата: 09.02.13 20:45
Оценка:
Здравствуйте, __kot2, Вы писали:

__>какой-то камменоугольного века код


Ну в целом да . Ручонки еще не отросли и малость кривоваты . Пишу как лучше понимаю .

__>если прямо сильно хочется иметь доступ к элементам и по имени и по очереди, то можно их запихать все в std::map


Спасибо . Посмотрю .
Re[2]: Обращение к структуре в цикле ?
От: DrunkPilot  
Дата: 09.02.13 20:49
Оценка:
J>
J>enum
J>{
J>    login,
J>    passwd,
J>    balance,
J>    email,
J>    phone,
J>    и тд...,
J>    last
J>};

J>wstring  data[last];

J>for each(wstring& in data)...
J>


J>Кул?


Полагаю да . Enum спасет отца русской демократии . Пионерское Вам спасибо .
Re[2]: Обращение к структуре в цикле ?
От: DrunkPilot  
Дата: 09.02.13 20:56
Оценка:
NT>Или сразу так, если это Ваша структура, и Вы можете модифицировать её определение:

NT>
NT>#include <cstring>
NT>#include <iostream>
NT>#include <boost/fusion/include/define_struct.hpp>
NT>#include <boost/fusion/include/for_each.hpp>

NT>BOOST_FUSION_DEFINE_STRUCT(
NT>    (), userdata,
NT>    (wchar_t*, login)
NT>    (wchar_t*, passwd)
NT>    (wchar_t*, balance)
NT>    (wchar_t*, email)
NT>    (wchar_t*, phone)
NT>    )

NT>struct Foo
NT>{
NT>    template <typename T>
NT>    void operator()(T& bar) const
NT>    {
NT>        bar = new wchar_t[256];
NT>        wcscpy(bar, L"Some Data");
NT>    }
NT>};

NT>int main()
NT>{
NT>    userdata instance;
NT>    boost::fusion::for_each(instance, Foo());

NT>    std::wcout << instance.login << '\n'
NT>            << instance.passwd << '\n'
NT>            << instance.balance << '\n'
NT>            << instance.email << '\n'
NT>            << instance.phone << '\n';
NT>}
NT>


NT>Кстати, зачем Вам понадобились wchar_t*, а не std::wstring, например?


Спасибо . Я правда не ждал такой развернутый ответ . К сожалению , в бусте я на данный момент ни в зуб ногой . Но надеюсь через полгодика разберусь и применю по назначению .
Re[3]: Обращение к структуре в цикле ?
От: __kot2  
Дата: 09.02.13 21:57
Оценка:
Здравствуйте, DrunkPilot, Вы писали:
DP>Здравствуйте, __kot2, Вы писали:
__>>какой-то камменоугольного века код
DP>Ну в целом да . Ручонки еще не отросли и малость кривоваты . Пишу как лучше понимаю .
код нормальный для Си. Но сама структура — пользователь, пароль, e-mail говорит что это какая-то клиент-серверная БД веб-ерунда (коей я, например, сейчас тоже занимаюсь) а для этого Си использовали лет 30 назад, скорее всего сам выбор языка плох или книжка, на которую вы опираетесь в С++. могу поспорить это очень старая книжка. вместо того, чтобы писать много сложноотлаживаемого и сложноподдерживаемого кода вам для этой области стоит выбрать, например C# и потратить время на изучение современных подходов. иначе потом все равно все переписывать придется, а на C# все тяп-ляп и готово и нету, например, никаких проблем с выделениями памяти, сериализацией, юникодом, разработкой интерфейса и прочим.
Re[2]: Обращение к структуре в цикле ?
От: Константин Россия  
Дата: 09.02.13 23:02
Оценка:
Здравствуйте, johny5, Вы писали:

J>[/ccode]

J>for each(wstring& in data)...
J>[/ccode]

J>Кул?


Нет не кул. Даже представители MS рекомендуют не пользоваться этим нестандартным костылём (здесь):


> I have a question: you briefly mentioned some gotchas when using for each.
> Did you mean the C++/CLI for each (int i in v), that is also available in unmanaged code?

Yes, that non-Standard extension. (Also, "native" please, not "unmanaged".)

> I am working on our coding guidelines and I would be interested what those gotchas are

It doesn't permit in-place modification (through modifiable references). The code that the compiler generates for "for each" contains a static_cast and some other weirdness in it, and I'm not sure exactly what it's doing. That's why I strongly recommend against using it. It's just not worth it.

> and what you recommend instead.

Anything else. Handwritten iterator loops (now with auto), STL algorithms (now with lambdas), BOOST_FOREACH, whatever.

for_each() is kind of the least useful STL algorithm (its main virtue is that it says what it does, whereas all handwritten iterator loops have to be inspected to see what they're doing). transform() is most useful for transforming one sequence into another, instead of doing in-place transformations (which it's certainly capable of).

The ultimate solution will be C++0x's range-based for-loop, when it's implemented.

Stephan T. Lavavej, Visual C++ Libraries Developer

Re[4]: Обращение к структуре в цикле ?
От: DrunkPilot  
Дата: 10.02.13 01:29
Оценка:
Книжка вроде нормальная . Философия c++ Эккеля . Просто пришлось параллельно разбираться с libcurl , незнакомым контролом , еще данные хранить надо где-то . В xml или json по идее . Надо еще библиотеку прикрутить . В общем решил с языком пока не заморачиваться и делать как получается . Может со временем , когда разберусь полность с плюсами , и перейду в C# .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.