Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > как преобразовать значение из файла в переменную?


Автор: BlackSkull 20.6.2016, 22:12
Приложение должно считывать из файла(.ini) значения width и height. При создании окна использовать эти параметры. Но, при запуске, открывается input.c и указывает на строку:

Код

if ( integer64 )
                                    *(__int64 UNALIGNED *)pointer = (unsigned __int64)num64;
                                else
                                if (longone)
                     =========>     *(long UNALIGNED *)pointer = (unsigned long)number;
                                else
                                    *(short UNALIGNED *)pointer = (unsigned short)number;



Как я понимаю, полученное значение(8 байт), превышает допустимый(4 байта).

Есть две структуры:
Код

struct ConfigStruct
    {
      int iSW, iSH;
    }ini;

    struct ConfigResult
    {
      int cSW, cSH;
    }res;



В ConfigStruct, записываются полученные из файла значения. В ConfigResult, я хотел записать преобразованные в int значения.

Код

int ConfigRW::ReadConfig(char* filename)
{
    ifstream fcf;

    string line;
    fcf.open(filename,ios::in);

    while (!fcf.eof())
    {
        getline(fcf,line);

        if(line.find("iScreenWidth = ")!=line.npos)
        {
            sscanf_s(line.c_str(),"iScreenWidth = %d",&ini.iSW);
            //Нужно преобразовать значения в int
            res.cSW = ini.iSW;
        }
        if(line.find("iScreenHeight = ")!=line.npos)
        {
            sscanf_s(line.c_str(),"iScreenHeight = %d",&ini.iSH);
            //Нужно преобразовать значения в int
            res.cSH = ini.iSH;
        }
    }
    fcf.close();
    return 0;
}


В WinMain, присвоить значения из структуры ConfigResult, к переменным: ScreenWidth, ScreenHeight. 

Код

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevious, LPSTR lpCmdLine, int nCmdShow)
{
    Config->ReadConfig("../Test/Settings.ini");
    int ScreenWidth, ScreenHeight;

    ScreenWidth = Config->res.cSW;
    ScreenHeight = Config->res.cSH;
    //ScreenWidth = 1280;
    //ScreenHeight = 720;

    Prog->WinClass(hInstance);
    Prog->WinCreate(hInstance,"Test Application",ScreenWidth, ScreenHeight);
    Prog->WinLoop(msg);
}


Подскажите, пожалуйста, как правильно преобразовать значения?

Автор: vol4ek 21.6.2016, 12:03
GetPrivateProfileString() потом atoi(S.c_str())

Автор: BlackSkull 21.6.2016, 15:44
Цитата

GetPrivateProfileString() потом atoi(S.c_str())


Боюсь, моего скромного уровня знаний не хватит.

Как я понял из документации, необходимо написать так:

Код

int ConfigRW::ReadConfig(char* filename)
{
    char RetStr [4096];

    ini.iSW = GetPrivateProfileStringA("Dispaly Settings","iScreenWidth",NULL,RetStr,4096 * sizeof(char),filename);
    res.cSW = atoi(RetStr);
    ini.iSH = GetPrivateProfileStringA("Dispaly Settings","iScreenHeight",NULL,RetStr,4096 * sizeof(char),filename);
    res.cSH = atoi(RetStr);
    
    return 0;


Пишет: чтение памяти невозможно. RetStr возвращает необходимое значение, но подсвечен красным. Переменные iSW,iSH,cSW,cSH = ???

Автор: tierswar 21.6.2016, 16:24
Может быть, в функции "ReadConfig" установить позицию в файле fcf на начало числа "высота", а затем сделать
как-то так
Код

fcf >> ini.iSH;


Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/kak-preobrazovat-znacheniye-iz-fayla-v-peremennuyu-id576840b5ae201515158b4567#findElement_E7045_57693ff0ae20158e6f0482cd_0

Автор: tierswar 21.6.2016, 16:24
насколько я понимаю, тогда "всё само там сделается" 

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/kak-preobrazovat-znacheniye-iz-fayla-v-peremennuyu-id576840b5ae201515158b4567#findElement_E7045_57694024ae2015ac6d04865b_0

Автор: vol4ek 21.6.2016, 16:29
максимальная длинна строки для функции 256 символов. зачем вы юзаете столько памяти для строк которые содержат всего 4 символа. (мониторов с разрешением более 10к не встречал) 

Автор: vol4ek 21.6.2016, 16:44
Код

4096 * sizeof(char)

это какое-то новое извращение, которого я еще не видел. 
Код

char str[10];
GetPrivateProfileStringA("бла-бла", "бла-бла", NULL, str, sizeof(str) - 1, "бла-бла");

проверки не забудьте.

Автор: BlackSkull 21.6.2016, 18:10
Указывает на строку:
Код

res.cSW = atoi(RetStr);


В коде:
Код

GetPrivateProfileStringA("Dispaly Settings","iScreenWidth",NULL,RetStr,sizeof(RetStr)-1,filename);
res.cSW = atoi(RetStr);


cSW,cSH - <чтение памяти невозможно>
Не понимаю. Может, с переменными(int cSW, cSH) что-то не так?

Автор: vol4ek 21.6.2016, 18:43
накосячили со структурой

Автор: vol4ek 21.6.2016, 19:18
сделайте конструктор инициализирующий свойства структуры раз вы запихнули ее в класс
http://rsdn.ru/forum/cpp/2938455.all

Автор: BlackSkull 21.6.2016, 20:55
Цитата

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


Не помогло. Та же ошибка. Может есть другой вариант осуществления задуманного?

Автор: vol4ek 21.6.2016, 23:04
все помогло я собирал ваш проект на работе.
делаете конструктор, а обращаться к переменным так:
Код

 class clsAngle
{
    private:

        struct strctCoordinate
        {
            short siGrad;
            float fMinutes;
            char cDirection;

            strctCoordinate(short siGrad_, float fMinutes_, char cDirection_) :
               siGrad(siGrad_), fMinutes(fMinutes_), cDirection(cDirection_) 
            {
            };
        };

        strctCoordinate NS, WE;


    public:

        clsAngle() : NS(0, 0, ' '), WE(0, 0, ' ')
        {
        }
}


Код

clsAngle myAngle;
myAngle.NS.siGrad = 0;

Автор: BlackSkull 22.6.2016, 13:58
Цитата

все помогло я собирал ваш проект на работе.
делаете конструктор, а обращаться к переменным так:


У меня, программа возвращает в ScreenWidth и ScreenHeight = -858993460.
Как я понял, считывает не те байты. С конструктором проблема. Я лишь умею создавать таким образом:

.h
Код

class DefClass
{
public:
Constructor();
~Constructor();
};


.cpp
Код

DefClass::Constructor()
{}
DefClass::~Constructor()
{}


А с конструктором, инициализирующим свойства структуры, впервые сталкиваюсь.

Вот, как я написал:
.h
Код

class ConfigRW
{
public:
    struct ConfigResult
    {
      int cSW, cSH;

      ConfigResult(int cSW_,int cSH_) : 
          cSW(cSW_), cSH(cSH_)
      {
      };
    };

    ConfigResult CRW;
public:
    ConfigRW() : CRW(0,0)
    {
    }
public:
    int ReadConfig(char*);
};


.cpp
Код

int ConfigRW::ReadConfig(char* filename)
{
    char RetStr [10];

    ConfigRW myConfig;

    GetPrivateProfileStringA("Dispaly Settings","iScreenWidth",NULL,RetStr,sizeof(RetStr),filename);
    myConfig.CRW.cSW = atoi(RetStr);
    GetPrivateProfileStringA("Dispaly Settings","iScreenHeight",NULL,RetStr,sizeof(RetStr),filename);
    myConfig.CRW.cSH = atoi(RetStr);
    
    return 0;
}


Я ничего не понимаю. Скажите, пожалуйста, как правильно это написать?
P.S. Извините, что надоедаю.

Автор: xvr 3.7.2016, 21:28
Ваш код можно отправлять на соревнование 'как сделать простое действие максимально сложным способом'  smile 

Исправьте ReadConfig так:

Код

int ConfigRW::ReadConfig(char* filename)
{
    char RetStr [10];
    GetPrivateProfileStringA("Dispaly Settings","iScreenWidth",NULL,RetStr,sizeof(RetStr),filename);
    CRW.cSW = atoi(RetStr);
    GetPrivateProfileStringA("Dispaly Settings","iScreenHeight",NULL,RetStr,sizeof(RetStr),filename);
    CRW.cSH = atoi(RetStr);
    
    return 0;
}


А еще лучше вообще не вводить ConfigResult -  в вашем воплощении он никакой полезной сущности не представляет.

Код

class ConfigRW
{
public:
      int cSW, cSH;
public:
    ConfigRW() : cSW(0), cSH(0)
    {
    }
public:
    void ReadConfig(char*);
};


Код

void ConfigRW::ReadConfig(char* filename)
{
    char RetStr [10];
    GetPrivateProfileStringA("Dispaly Settings","iScreenWidth",NULL,RetStr,sizeof(RetStr),filename);
    cSW = atoi(RetStr);
    GetPrivateProfileStringA("Dispaly Settings","iScreenHeight",NULL,RetStr,sizeof(RetStr),filename);
    cSH = atoi(RetStr);
}


Автор: BlackSkull 6.7.2016, 18:40
xvr, спасибо за ответ. Сделал так, как Вы сказали. Все равно, приложение считывает не те байты. Возвращает значение -858993460. smile 
Может, с файлом .ini что то не так или с самим проектом?
Ссылка прилагается.

Автор: xvr 7.7.2016, 22:13
У вас не созданы классы, к которым вы обращаетесь:
Код

Program* Prog = NULL;
ConfigRW* Config = NULL;
MSG msg;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevious, LPSTR lpCmdLine, int nCmdShow)
{
    int ScreenWidth, ScreenHeight;
    Config->ReadConfig("../Test/Settings.ini");

    ScreenWidth = Config->cSW;
    ScreenHeight = Config->cSH;

    Prog->WinClass(hInstance);
    Prog->WinCreate(hInstance,"Test Application",ScreenWidth, ScreenHeight);
    Prog->WinLoop(msg);
}
Я вообще очень удивлен, что это работает - должен быть крах приложения при запуске.
Измените код так:
Код

Program Prog;
ConfigRW Config;
MSG msg;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevious, LPSTR lpCmdLine, int nCmdShow)
{
    int ScreenWidth, ScreenHeight;
    Config.ReadConfig("../Test/Settings.ini");

    ScreenWidth = Config.cSW;
    ScreenHeight = Config.cSH;

    Prog.WinClass(hInstance);
    Prog.WinCreate(hInstance,"Test Application",ScreenWidth, ScreenHeight);
    Prog.WinLoop(msg);
}


Автор: BlackSkull 8.7.2016, 12:44
Цитата

Я вообще очень удивлен, что это работает - должен быть крах приложения при запуске.
Измените код так:

Код

Program Prog;
ConfigRW Config;
MSG msg;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevious, LPSTR lpCmdLine, int nCmdShow)
{
    int ScreenWidth, ScreenHeight;
    Config.ReadConfig("../Test/Settings.ini");
    ScreenWidth = Config.cSW;
    ScreenHeight = Config.cSH;
    Prog.WinClass(hInstance);
    Prog.WinCreate(hInstance,"Test Application",ScreenWidth, ScreenHeight);
    Prog.WinLoop(msg);
}



Большое вам спасибо, xvr. Действительно, после создания классов в файле Main.cpp, приложение заработало корректно.
Ссылку на рабочий проект я оставлю(вдруг кому-нибудь пригодится). Спасибо всем, кто принимал участие в обсуждении.
На этом, тему можно считать закрытой.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)