Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по программированию на C/С++

Автор: asi81
Дата сообщения: 21.01.2010 19:07
Запутался в элементарном действии.
Есть строка TCHAR[]. Нужно перевести ее к char[]. Какой функцией это сделать?
Автор: Abs62
Дата сообщения: 21.01.2010 19:27
asi81

Цитата:
TCHAR: A WCHAR if UNICODE is defined, a CHAR otherwise.

Так она WCHAR или CHAR?
Автор: BednuuStudent
Дата сообщения: 21.01.2010 21:23
Помогите плз
Мне надо подробно описание всех функций програми
[more]

Код:
#include <iostream.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <conio.h>

const int SIZE_J=5;
const int SIZE_I=4;

void gauss(float[][SIZE_J], int, int, int);
void gauss_tmp(float[][SIZE_J]);

void main()//Создаем пустую функцию для ввода параметров.
{
clrscr()//отчищаем дисплей;
Float mas[SIZE_I][SIZE_J]={{4,5,6,7,1},{8,9,10,11,2},{12,3,3,5,3},{16,-1,-2,3,4}};//создаем матрицу размером IxJ


    float sum=0; // инициализируем переменную sum,задавая ей начальное значени 0
    int kod;//объявляем переменную kod как int(целочисленную) в диапазоне -32767 - 32767
    printf("Danaya programa vu4iclyaet CLAY metodom Dgordano-Gaysa\n\n"); //используемых для форматного вывода — вывода в различные потоки значений разных типов, //отформатированных согласно заданному шаблону. Этот шаблон определяется составленной по //специальным правилам строкой (форматной строкой).

    printf("1 na4at\n0 vuxod\n\n\n");

    {


        kod=getch();// в переменную kod заносим значение введенное с
// клавиатуры(getch()-читает без эхо-отображения отдельный символ
// прямо с консоли. Напечатанные (введенные) символы не имеют
// эхо-отображения. Если введен CONTROLL-C, система выполняет INT
// 23H.)

        switch(kod); //вычисляется выражение в круглых скобках после оператора switch //(предварительная стадия);
//это значение последовательно сравнивается со значениями константных выражений за метками case //(стадия определения начальной точки выполнения оператора);
//    если значения совпадают, управление передаётся соответствующему помеченному оператору (стадия //выполнения);
//     если ни одно значение не совпадает и в теле оператора case есть оператор, помеченный меткой //default, управление передаётся этому оператору (но даже в этом случае сочетание объявления с //инициализацией недопустимо!) (стадия выполнения);
// если ни одно значение не совпадает, и в теле оператора case нет оператора, помеченного меткой //default, управление передаётся оператору, следующему за оператором switch (стадия выполнения).
        {
        case 49:
            {
                gauss_tmp(mas);
                printf("\n\n\nnajmite liubuiu klavishu dla vuxoda");
                getch();
            }break;

        case 48:
            {
                exit(0);
            }break;
        }
    }



}

void gauss_tmp(float mas[][SIZE_J]) //возвращаемая функция
//тип_возврата имя_функции(список_параметров)
//{
// Тело_функции
//}

{
    float mas_tmp[SIZE_I][SIZE_J];
    for(int i=0;i<SIZE_I;i++) //цикл for позволяет выполнить автоматическую //инициализацию и инкременирование переменной счетчика
// for(инициализация; условие; инкримент)
// {
// блок_операторов
// }

    {
        for(int j=0;j<SIZE_J;j++)mas_tmp[i][j]=mas[i][j];
    }

    gauss(mas_tmp,SIZE_I,SIZE_J,0);
}

void gauss(float mas[][SIZE_J], int size_i, int size_j, int start) //возвращаемая //функция
{
    float x, y, z, t;
    if(start==size_j-2)
    {
        int i=0;
        t=mas[i][size_j-1]/mas[i][start]; i++; start--;
        z=(mas[i][size_j-1]+t)/mas[i][start]; i++; start--;
        y=(mas[i][size_j-1]+t+z)/mas[i][start]; i++; start--;
        x=(mas[i][size_j-1]+t+z+y)/mas[i][start]; i++; start--;

        printf("x=%f\nx=%f\nx=%f\nx=%f\n",x,y,z,t);

        return;
    }

    float del;
    float tmp;

    for(int i=0;i<=size_i-(start+1);i++)
    {
        del=mas[i][start];

        for(int j=0;j<size_j;j++)
        {
            mas[i][j]=mas[i][j]/del;
        }
    }


    for(int j=0;j<size_j;j++)
    {
        tmp=mas[0][j];
        mas[0][j]=mas[size_i-(start+1)][j];
        mas[size_i-(start+1)][j]=tmp;
    }


    for(i=0;i<size_i-(start+1);i++)
    {
        for(int j=0;j<size_j;j++)
        {
            mas[i][j]=mas[size_i-(start+1)][j]-mas[i][j];
        }
    }

    gauss(mas,size_i,size_j,start+1);

}
Автор: somereal
Дата сообщения: 21.01.2010 22:40
BednuuStudent
у тебя же и так всё описано, что ещё надо? литературное обрамление чтоли?
Автор: KChernov
Дата сообщения: 22.01.2010 05:43
somereal

Цитата:
у тебя же и так всё описано, что ещё надо?

Если вчитаться - прокомментировано криво(по крайней мере для не учебной программы).

BednuuStudent

Цитата:
Мне надо подробно описание всех функций програми

Пока не указана цель, что-то лучше того, что уже есть , вряд ли кто-то предложит.
Автор: BednuuStudent
Дата сообщения: 22.01.2010 09:51
мне там надо описание нижних функций там где идут сами функции gauss
Автор: asi81
Дата сообщения: 22.01.2010 11:43
Abs62
В том и дело что это TCHAR. Причем компилируется в нескольких проектах и с использованием Unicode и без использования. Соответственно без юникода - это char, с юникодом это wchar. На то он и Tchar чтобы я не думал об этом. Конечно можно тупо самому написать макрос или функцию, что я и сделал, но вообще логика подсказывает, что если введен Tchar, то должны быть и макросы, работающие конкретно с ним.
Автор: TargeTSan
Дата сообщения: 22.01.2010 11:44
BednuuStudent
На будущее. В любой нормальной конторе за транслит бьют по шее, причём больно.
Учите английский и управление локалями.
За описанием CRT идите в MSDN.

И последнее. Для ленивых студентов есть отдельный форум "Задачи С++"
(Хотя, подозреваю, там уже давно никто не отвечает )

Добавлено:
asi81
А не могли бы Вы уточнить задачу?
Что Вы будете делать с получившейся LPCSTR?

Вообще же такое преобразование неоднозначно, поскольку wchar_t это по сути кодировка UTF16 (номер 1200). Поэтому Вам необходимо знать, какую кодировку требуется получить на выходе. Конверсия между UTF8/UTF16/UTF32 производится простой перетасовкой битов, без таблиц кодировок, посколько это просто 3 разных представления UNICODE

В WinAPI смотрите WideCharToMultiByte и MultiByteToWideChar.
Для кроссплатформы есть libiconv.
Автор: asi81
Дата сообщения: 22.01.2010 13:30
TargeTSan
Кодировка в данном случае меня не волнует, так как все работа идет с английским текстом. Суть в том, что я имею проект, где используется tchar, в частности в аргументах командной строки. Этот проект компилируется под разными платформами, и tchar в разных платформах может быть либо char либо WCHAR. В одном месте мне нужно привести строку TCHAR[] к строке char[]. Если использовать WideCharToMultiByte или его аналог wcstombs, то в проекте без юникода компилятор законно выдаст ошибку, так как эти функции(WideCharToMultiByte) в качестве источника принимают WHAR, в то время как tchar превратился в char.

Конечно можно написать макрос типа
#ifdef UNICODE
#define myfun wcstombs
#else
#define myfun strncpy
#enfif

Но неужели такой макрос уже не написан?
Автор: karakurt2
Дата сообщения: 22.01.2010 15:52
asi81
наберите strncpy в MSDN, и увидете, что макросы определены в файле <tchar.h>.
Автор: asi81
Дата сообщения: 22.01.2010 17:41
karakurt2
Я посмотрел, но сразу там не увидел. Возможно Вы имеете ввиду функцию _tcsncpy которая копирует tchar[] строки. Мне же нужно не копирование, а именно перевод из tchar[] строки в char[] строку. Которая в случае Unocode превращается в wcstombs(..), а без юникода в strncpy. По крайней мере с первого прохода я такой макрос не засек.
Автор: Abs62
Дата сообщения: 22.01.2010 18:21
asi81
А зачем вообще использовать char[] в юникодной программе?
Автор: asi81
Дата сообщения: 22.01.2010 18:38
Abs62
Грубо говоря, есть уже написанный программный модуль, который был написан давно. Этот программный код может использоваться в других компиляторах, которые о ни о tchar, ни о wchar могут не подозревать. Поэтому менять уже написанный и отлаженный код я не хочу. Но хочу его использовать в Win32 и в Win32_WCE программах. А Win32_WCE программы, к примеру, не имеют неюникод_поддержки в принципе, то есть они работают исключительно с Unicode.
Автор: Abs62
Дата сообщения: 22.01.2010 19:23
asi81
Тогда остаётся лишь самому написать столь же отлаженный интерфейс к этому модулю. И свалить туда всю работу по адаптации char/tchar. Вряд ли найдутся готовые функции для создания такой смеси.
Автор: hda0
Дата сообщения: 22.01.2010 20:54
ValidolX
проблема осталась
cегодня произошел обвал снова.
Вы еще можете глянуть исходники на предмет баги? где то может еще стопорится очередь.
обновлённые исходники лежат тут...

з.ы. также обращаюсь к всем спецам по С/С++, гляньте сырцы пжлст на предмет баги...
Автор: ValidolX
Дата сообщения: 22.01.2010 21:58
hda0
а есть ли какие-то логи где видно проблему?
обновлённые исходники ОК
Автор: hda0
Дата сообщения: 22.01.2010 23:07
ValidolX
нет, в логах не видно ничего такого.
юзера авторизуються, и при большом наплыве очередь растёт, она не успевает обработаться, и NAS не получает ответа от radius-auth, после чего юзера получают ошибку 718. тестировал и на дуал коре, и на квадрокоре, одинаково. т.е. размер оперативки и мощность проца роли не играет никакой. где то бага ещё осталась в программном коде
Автор: deman_ru
Дата сообщения: 23.01.2010 21:02
Помогите пожалуйста сформировать сложный sql запрос.
Имеется таблица вида:

В ней отображается информация из таблицы базы данных, компонент для отображения DBGridEh, в начале каждой строки стоит CheckBox. У каждой записи есть свой идентификатор, мне нужно сформировать такой запрос, который бы выбирал данные из другой таблицы, относительно тех записей которые выбраны в первой (таблица выше). Сначала видимо нужно как то обработать, DBGridEh, а потом уже формировать запрос. Подскажите пожалуйста, хоть пару слов, натолкните на мысль!
Автор: ValidolX
Дата сообщения: 23.01.2010 21:21
deman_ru
1) ето НЕ сложный sql запрос
2) Я так понимаю что чекбокс мапиться на поле с таблице, да?
тогда пишете простой SQL запрос где обединяете две таблички по условию етого поля (true - если bool)
писать sql не буду, так как от того, что я напишу - знаний у вас не прибавиться, увы...
А чтоб прибавилось - надо проработать несколько уроков например отсюда

http://firststeps.ru/sql/sql1.html

3) Поверьте, потраченный час-другой та СОБСТВЕННОЕ развитие окупиться потом очень хорошо - или деньгами, или временем, или и тем и другим
Автор: deman_ru
Дата сообщения: 23.01.2010 22:02
ValidolX
я наверное неправильно выразил что хотел узнать, меня в большей степени интересует, как мне из DBGridEh выбрать id, отмеченных строк? какие применить свойства или функции?
А CheckBox делал так: в таблице сделал поле типа integer (1,0), оно у меня как логическое, потому что в СУБД Firebird, которую я использую, нет логического типа данных. В DBGridEh, на это поле установил свойство CheckBoxes=true, и KeyList 0;1.
Автор: ValidolX
Дата сообщения: 23.01.2010 23:11
deman_ru
ОК, теперь более понятно
насколько я понимаю (поправьте если не так) у вас дб грид связан с данными через DataSource.
Значит надо
а) пробежаться по всех записях DS грида
б) глянуть на значение в і-том рядке нужного поля (Field) - если критерий удовлетворен - узнаем id и запоминаем куда надо
пример - TDataSet *pDS = DBGrid1->DataSource->DataSet;
pDS->FieldByName("id")->AsInteger
...
с) рекомендуеться делать фриз гриду во время итераций по датасорсу (а то будет видно визуально что идет итерация по записям - DisableControls()/EnableControls() на датасорс->датасете (pDS)

Насколько я знаю дб грид не держит всех данных датасорса, поетому другого метода (видимо) нету кроме как итерации по датасорсу.
Автор: deman_ru
Дата сообщения: 24.01.2010 14:43
ValidolX
вот как я с этим справился, результат заносил в Memo построчно:

DataModule2->IBTable1->First();
int n=0;
while (!DataModule2->IBTable1->Eof)
{
int x;
x=DataModule2->IBTable1->FieldByName("CHEK")->AsInteger;
if (x==1)
{
Form1->Memo1->Lines->Add(DataModule2->IBTable1->FieldByName("ID_SIMTOM")->AsString);
n=n+1;
}
DataModule2->IBTable1->Next();
}

Вот теперь никак не приходит на ум, как сформировать запрос, понятно что он должен быть вида:
select diagnoz from rules where id_simptom=[1-я строка Memo] and id_simptom=[2-я строка Memo] and...id_simptom=[n-я строка Memo];

У Вас нет никаких идей?
Автор: ValidolX
Дата сообщения: 24.01.2010 15:02


deman_ru
улыбнуло!!!
мне б ваши проблемы .......
ну да ладно, к сути да делу

теория
для выборки данных будем использовать SQL селект следующей конструкции

SELECT X FROM Y WHERE Z IN (A,B,C,...)

осталось только правильно сформировать строку strFilter -> A,B,C...
тут можно
а) сразу формировать strFilter
б) после вашего цикла еще раз пробежаться по мемо и сформировать

вар. а более интересен, делаем:


Код:
AnsiString strFilter;
DataModule2->IBTable1->DisableControls();
DataModule2->IBTable1->First();
while (!DataModule2->IBTable1->Eof)
{
if (1 == DataModule2->IBTable1->FieldByName("CHEK")->AsInteger)
{
if (!strFilter.IsEmpty())
strFilter += ", ";
strFilter += DataModule2->IBTable1->FieldByName("ID_SIMTOM")->AsString
}
DataModule2->IBTable1->Next();
}
DataModule2->IBTable1->EnableControls();

AnsiString strSql = "select diagnoz from rules where id_simptom IN ("+ strFilter + ")";
Автор: deman_ru
Дата сообщения: 24.01.2010 15:24
ValidolX
спасибо Вам огромнейшее! вы уж извените за мою "непонятливость" я только учусь, но хоть повеселил Вас
Автор: hda0
Дата сообщения: 29.01.2010 09:38
помогите найти мелкую багу в этом кусочке кода..
трабла такая:
в БД указан срок действия аккаунта скажем "Jan 29 2010".
программа icradius при проверке этой даты на текущий момент 29 января - иногда пускает а иногда не пускает пользователя, типа истёк срок действия. причем срабатывает рандомно. например срабатывает на отказ в 8 случаях из 10.
я так понимаю: если скажем срок действия до 29 января, то должно юзера пускать до 2010-01-29 23:59:59 включительно. так?
почему так происходит? или может эта проблема не в этом блоке?

Код:
/*
* Tests to see if the users password has expired.
*
* Return: Number of days before expiration if a warning is required
* otherwise 0 for success and -1 for failure.
*/
static int pw_expired(UINT4 exptime)
{
struct timeval tp;
struct timezone tzp;
UINT4 exp_remain;
int exp_remain_int;

gettimeofday(&tp, &tzp);
if (tp.tv_sec > exptime)
return -1;

if (warning_seconds != 0) {
if (tp.tv_sec > exptime - warning_seconds) {
exp_remain = exptime - tp.tv_sec;
exp_remain /= (UINT4)SECONDS_PER_DAY;
exp_remain_int = exp_remain;
return exp_remain_int;
}
}
return 0;
}

* Check if account has expired, and if user may login now.
*/
static int check_expiration(VALUE_PAIR *check_item, char *umsg, char **user_msg)
{
int result;
int retval;

result = 0;
while (result == 0 && check_item != (VALUE_PAIR *)NULL) {

/*
* Check expiration date if we are doing password aging.
*/
if (check_item->attribute == PW_EXPIRATION) {
/*
* Has this user's password expired
*/
retval = pw_expired(check_item->lvalue);
if (retval < 0) {
result = -1;
*user_msg = "Password Has Expired\r\n";
break;
} else {
if (retval > 0) {
sprintf(umsg,
"Password Will Expire in %d Days\r\n",
retval);
*user_msg = umsg;
}
}
}
check_item = check_item->next;
}
return result;
}
Автор: ValidolX
Дата сообщения: 29.01.2010 09:47
hda0
Нет, не удалось, нужно практическую сессию сделать - если можно - подумайте как мне организовать тест (повторить багу у себя, есть линукс, винда)

2) по коду ничего не видно, покажите ка функцию pw_expired() - вот она и решает expired или нет
Автор: hda0
Дата сообщения: 29.01.2010 10:11
ValidolX
показал, чуть выше...

Добавлено:
ValidolX

Цитата:
Нет, не удалось, нужно практическую сессию сделать - если можно - подумайте как мне организовать тест (повторить багу у себя, есть линукс, винда)

над для начал придумать как симулировать нагрузку без самих пользователей
мож какого демона написать который будет делать примерно 200-250 запросов в секунду...
но как - не знаю.. есть в комплекте всех радиусов утилиты типа radtest, но они чекают по 1 запросу....
Автор: ValidolX
Дата сообщения: 29.01.2010 10:32

Цитата:
я так понимаю: если скажем срок действия до 29 января, то должно юзера пускать до 2010-01-29 23:59:59 включительно. так?


Покажите еще пож-та как определено
SECONDS_PER_DAY и
warning_seconds

а еще надо убедиться что check_item->lvalue в тех единицах что надо (секундах)
pw_expired(check_item->lvalue);

а так с виду код верен
Автор: hda0
Дата сообщения: 29.01.2010 10:43
ValidolX

Цитата:
Покажите еще пож-та как определено
SECONDS_PER_DAY и
warning_seconds

#grep SECONDS_PER_DAY *.h
radiusd.h:#define SECONDS_PER_DAY 86400

#grep warning_sec *.h
radiusd.h:extern UINT4 warning_seconds;
radiusd.h:extern UINT4 warning_seconds;

странно, почему то ворнинг_сек определен два раза....

что нибудь еще показать?

Добавлено:
p.s. в radiusd-auth.c нашел ещё одно упоминание об warning_seconds


Код:
/*
* Intializes configuration values:
*
* warning_seconds - When acknowledging a user authentication
* time remaining for valid password to notify user
* of password expiration.
*
* These values are read from the SERVER_CONFIG part of the
* dictionary (of all places!)
*/
int config_init()
{
DICT_VALUE *dval;

if((dval = dict_valfind("Password-Warning")) == (DICT_VALUE *)NULL) {
warning_seconds = (UINT4)0;
}
else {
warning_seconds = dval->value * (UINT4)SECONDS_PER_DAY;
}
return 0;
}
Автор: ValidolX
Дата сообщения: 29.01.2010 11:00
hda0
warning_seconds и SECONDS_PER_DAY в порядке

мне не до конца понятен етот while - он бегает по списку и ищет атрибут PW_EXPIRATION
вот, если Expired - ok, делаем брейк

а если нет - то бежим дальше - зачем?
логично делать брейк после первого найденного атрибута PW_EXPIRATION ?


Код:
static int check_expiration(VALUE_PAIR *check_item, char *umsg, char **user_msg)
{

.......[skipped]

if (check_item->attribute == PW_EXPIRATION) {
/*
* Has this user's password expired
*/
retval = pw_expired(check_item->lvalue);
if (retval < 0) {
result = -1;
*user_msg = "Password Has Expired\r\n";
break;
} else {
if (retval > 0) {
sprintf(umsg,
"Password Will Expire in %d Days\r\n",
retval);
*user_msg = umsg;
}
}
break;
}
check_item = check_item->next;
}
return result;
}

Страницы: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193

Предыдущая тема: не знаю как назвать тему :-)


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.