Привет всем!Возникла проблема создания динамичных переменных в C++.
К примеру, имееться переменная "value" типа char*, и имееться переменная "i" типа int.
Значение "i" не постоянное, и может меняться.
Нужно в цикле присоеденять значение "i" и названию переменной "value"То есть должно выйти: value1, value2, value3...
for ( int i = 0; i < somevalue; i++ ) {
// Должно выйти соединение названий переменныхтипа value + i;
или как на Perl $value$i}
Зарание списибо за ответ.
>Возникла проблема создания динамичных переменных в C++.C++ - компилируемый язык, а не интерпретируемый.
>>Возникла проблема создания динамичных переменных в C++.
>
>C++ - компилируемый язык, а не интерпретируемый.Но решить эту проблему все же как-то возможно ?!?
>Но решить эту проблему все же как-то возможно ?!?Конечно. Используй массив char *values[N].
>Привет всем!
>
>Возникла проблема создания динамичных переменных в C++.Это не совсем то что понимается под "динамичными переменными".
Вам просто нужно превратить число в строку и приписать к другой строке. Если это C++, то проще всего где-то так:
for ( int i = 0; i < somevalue; i++ ) {std::stringstream strm;
strm << value << i;
std::string newValue = strm.str();// do something with newValue
// ...}
То есть, создаете обьект класса stringstream который занимается форматированием строк (value может быть или char *, или std::string), а потом из этого обьекта получаете уже результирующую строку newValue.
>[оверквотинг удален]
> std::string newValue = strm.str();
>
> // do something with newValue
> // ...
>
>}
>
>То есть, создаете обьект класса stringstream который занимается форматированием строк (value может
>быть или char *, или std::string), а потом из этого обьекта
>получаете уже результирующую строку newValue.Задача стоит не в конкатенации переменных а в создании переменной из имен, то есть есть к примеру переменная value, нужно поочередно прилиплять к примеру числа от 1..10 так, чтобы создавались переменные value1, value2, value3 и т.д.
И чтобы к этой переменной можно было нормально обратиться как к другим переменным.
Вот про что я говорил.
А этот пример по всей видимости соединяет значение одной переменной с другой.
Но реальной переменной он не создает.Он создает к примеру переменную newValue которая имеет значение value + i, а нужно было создать переменную value + i.
Смотрел как это реализовать, можно TCL + C++ или писать на Java.
Есть идеи как реализовать штатными средствами C++?
Масивы не подходять.
>[оверквотинг удален]
>
>Но реальной переменной он не создает.
>
>Он создает к примеру переменную newValue которая имеет значение value + i,
>а нужно было создать переменную value + i.
>
>Смотрел как это реализовать, можно TCL + C++ или писать на Java.
>
>
>Есть идеи как реализовать штатными средствами C++?Да, извините, теперь я понял вопрос.
Нет, штатными средствами C++ - нельзя. Дело в том, что на этапе выполнения программы откомпилированной из исходного текста C++, информация об именах переменных уже утеряна. Eсли у вас есть набор простых переменных
int value1;
...
int value10;для программы их имена ничего не значат, программа манипулирует просто их адресами в памяти. Даже если вы думаете об использовании RTTI - в C++ он очень ограничен.
Java, будучи по сути "вещь в себе", тянет за собой намного больше информации чем C++ на этап выполнения - что и позволяет использовать reflection чтобы получить доступ к именам переменных (да и то, я не уверен что reflection позволяет обратиться к локальным переменным).
TCL + C++ - наверно вы имеете в виду использование переменных TCL, а не C++, и доступаться к ним путем вызова какой-то функции среды TCL?
Тогда эквивалентное по эффективности средство - std::map с ключами типа "value1" ... "valueN":
std::map myMap;
for ( int i = 0; i < somevalue; i++ ) {
std::stringstream strm;
// Create a key for the map.
strm << "value" << i;
std::string key = strm.str();// Clear the stingstream.
strm.rdbuf()->str("");// Create value.
strm << "a" << i;
std::string val = strm.str();// Create a value in the map.
myMap[key] = val;
}Теперь доступ к таким "переменным" - myMap["value1"], myMap["value2"] и т. д.
>[оверквотинг удален]
> std::string val = strm.str();
>
>
> // Create a value
>in the map.
> myMap[key] = val;
>
> }
>
>Теперь доступ к таким "переменным" - myMap["value1"], myMap["value2"] и т. д.Ура! Работает! Спасибо elvenic!
Вот рабочий пример:
#include <iostream>
#include <sstream>
#include <map>std::map <std::string, std::string> myMap;
int main() {
for ( int i = 0; i < 10; i++ ) {
std::stringstream strm;
// Create a key for the map.
strm << "value" << i;
std::string key = strm.str();// Clear the stingstream.
strm.rdbuf()->str("");// Create value.
strm << "a" << i;
std::string val = strm.str();// Create a value in the map.
myMap[key] = val;
}
std::cout << myMap["value1"] << std::endl;
std::cout << myMap["value2"] << std::endl;
std::cout << myMap["value3"] << std::endl;return 0;
}
//Вариант без STL:for(int i = 0; i < somevalue; i++)
{
char TempBuff[TEMP_BUFF_SOME_LENGTH];
snprintf(TempBuff, TEMP_BUFF_SOME_LENGTH, "%s %d\0", value, i);
}
>//Вариант без STL:
>
>for(int i = 0; i < somevalue; i++)
>{
> char TempBuff[TEMP_BUFF_SOME_LENGTH];
> snprintf(TempBuff, TEMP_BUFF_SOME_LENGTH, "%s %d\0", value, i);
>}То же случай вроде. В C не очень...
Ну и в чем у вас затруднение? Как число в строку превратить? Вариантов, как минимум, три (boost::lexical_cast, s[n]printf, и что-то там с потоками). Ищите в гугле.
Состав переменных программы на языке C++ фиксируется на этапе компиляции и по определению не может зависеть от (вообще говоря, изменяемого в процессе исполнения программы) количества итераций цикла. Некий синтаксический сахар подобного рода можно изготовить с помощью макросов, но это - убогий костыль, не более.Таким образом, в поставленной форме проблема не решается. Основная причина - на уровне конструкций языка C++ нет средств по манипулированию конструкциями языка. Фокус тут не в интерпретируемости/компилируемости, а в отсутствии встроенного в runtime-среду кодового генератора. Скажем, Java - среда компилируемая, но там есть Reflection API.
Исходная проблема, честно говоря, непонятна. Для манипулирования *данными* в C++ есть все необходимое плюс еще чуть-чуть, а потребность "на лету" управлять составом переменных сродни соревнованиям по бегу в мешках.
Зачем такие сложности.Создай двух мерный массив.
char ** value;
int i;
value = new ( char *)[i];Вот у тебя массив динамических переменных.
>
>Зачем такие сложности.
>
> Создай двух мерный массив.
> char ** value;
> int i;
> value = new ( char *)[i];
>
> Вот у тебя массив динамических переменных.Спасибо, пробывал работает.
Но вот в Qt4 не работает.Сильно спростил, чтобы показать суть:
QLCDNumber **lcd = new QLCDNumber *[10];
...
for ( int i = 0; i < 10; ++i ) {
...
lcd[i] -> setNumDigits ( 3 );
...
}Вылетает в кору (Ошибка сегментирования)
Как только я хочу применить к объекту какой-то метод ( в данном случае setNumDigits ) - приложение падает даже не запустившись.
Не знаете почему?
>[оверквотинг удален]
> lcd[i] -> setNumDigits ( 3 );
>...
>}
>
>Вылетает в кору (Ошибка сегментирования)
>
>Как только я хочу применить к объекту какой-то метод ( в данном
>случае setNumDigits ) - приложение падает даже не запустившись.
>
>Не знаете почему?Вот это глюк. На сайте показывает lcd -> setNumDigits ( 3 ); а должно быть lcd <квадратная скобка> i <квадратная скобка> -> setNumDigits ( 3 );
На почте и при ответе все нормально...
>[оверквотинг удален]
>for ( int i = 0; i < 10; ++i ) {
>
>...
> lcd[i] -> setNumDigits ( 3 );
>...
>}
>
>Вылетает в кору (Ошибка сегментирования)
>
>Не знаете почему?Знаем конечно. После new QLCDNumber *[10] каждый lcd[i] содержит мусор. Тебе сначала надо сделать что-то типа
lcd[i] = new QLCDNumber();
а потом уже пытаться обращаться к lcd[i]->anything
>Знаем конечно. После new QLCDNumber *[10] каждый lcd[i] содержит мусор. Тебе сначала
>надо сделать что-то типа
>lcd[i] = new QLCDNumber();
>а потом уже пытаться обращаться к lcd[i]->anythingЧто-то покоцался текст в предыдущем посте.
>>Знаем конечно. После new QLCDNumber *[10] каждый lcd[i] содержит мусор. Тебе сначала
>>надо сделать что-то типа
>>lcd[i] = new QLCDNumber();
>>а потом уже пытаться обращаться к lcd[i]->anything
>
>Что-то покоцался текст в предыдущем посте.Какому [censored] пришло в голову цеплять рюшечки с курсивом на форуме технарей?
>>Знаем конечно. После new QLCDNumber *[10] каждый lcd[i] содержит мусор. Тебе сначала
>>надо сделать что-то типа
>>lcd[i] = new QLCDNumber();
>>а потом уже пытаться обращаться к lcd[i]->anything
>
>Что-то покоцался текст в предыдущем посте.Я про это и говорю... У меня то же ( см. выше )
>[оверквотинг удален]
>>}
>>
>>Вылетает в кору (Ошибка сегментирования)
>>
>>Не знаете почему?
>
>Знаем конечно. После new QLCDNumber *[10] каждый lcd[i] содержит мусор. Тебе сначала
>надо сделать что-то типа
>lcd[i] = new QLCDNumber();
>а потом уже пытаться обращаться к lcd[i]->anythingСпасибо добрый человек, работает!
Извените за ламерские вопросы, просто начинающий :)
И так, небольшой итог как можно решить задачу:QLCDNumber **lcd = new QLCDNumber *[15];
lcd [ i ] = new QLCDNumber;
lcd [ i ] -> setNumDigits ( 3 );
lcd [ i ] -> display ( L );Это пример для Qt. Конечно вместо QLCDNumber ставим нужный тип данных.
Шаблон понятный.Темы закрыта.
БОЛЬШОЕ спасибо всем кто помогал!