Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C++ Builder
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.03.2013, 03:26   #1
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию Не могу обратиться к i-той ячейке const char.

for moderators
Поменяйте название темы, пожалуйста. :-[ . Когда начал создавать тему, была одна ошибка, потом её поборол, вставил новый код, а название забыл поменять. Теперь траблы с обращением к памяти.

Здравствуйте, владеющие тайными знаниями незнакомцы.
Делаю по заданию из книги перевод из 10-ой в 16-ричную СС. Компилятор на делфи был поумнее, а я был потупее. Пришло время поумнеть, и сбросить с компилятора невыносимую ношу.
На обозрение мой недокоТ:
Код:
#include <iostream.h>
#include <conio.h>
#include <cstring.h>
#include <alloc.h>

void convert (__int64,int,char*&);

int i=1;
const char* d="0123456789ABCDEF";
main()
{
  __int64 TChislo;
  char* result=0;
  int TCC;
  cout<<"BBeDuTe 4uc/|o\n";
  cin>>TChislo;
  cout<<"BBeDuTe B KaKy|-O CC nepeBoDuM\n";
  cin>>TCC;
  result=(char*)realloc(result,sizeof(char)*2);
  convert(TChislo,TCC,result);
  cout<<result;
  result=(char*)realloc(result,0);
  getch();
}

void convert (__int64 chislo, int CC,char* &result)
{
  int c=chislo%CC;
  chislo=chislo/CC;
  i++;
  result=(char*)realloc(result,sizeof(char)*i);
  if (chislo>0) convert(chislo,CC,result);
  result=strncpy(result,(char*) d[c+1],1);
}
Какие косяки бросаются в глаза?
Access Violation опять вылезает .
Прошу помощи у Вас, Гуру.
Заранее благодарен.
( offtop: как-то непутево звучит это "Заранее благодарен".)
Если помог, проси поставить минус. Будь оригинален!

Последний раз редактировалось Rin; 30.03.2013 в 03:31.
Rin вне форума Ответить с цитированием
Старый 30.03.2013, 09:41   #2
FataLL
Форумчанин
 
Аватар для FataLL
 
Регистрация: 29.01.2013
Сообщений: 319
По умолчанию

Ну, во-первых...
Код:
result = strncpy( result, (char*) &d[c+1], 1 ); // & - большая разница
Во-вторых...
Код:
result = strncpy( result, (char*) &d[c], 1 ); // не надо 1 прибавлять
В-третьих, ты постоянно копируешь текущую цифру в первую ячейку, что неправильно. Надо добавлять в конец строки. Предлагаю такой код
Код:
void convert (__int64 chislo, int CC,char* &result)
{
  int c=chislo%CC;
  chislo=chislo/CC;
  i++;
  result=(char*)realloc(result,sizeof(char)*i);
  if( chislo > 0 )
    convert(chislo,CC,result);
  int nLen = strlen( result );
  result[ nLen++ ] = d[c];
  result[ nLen ] = '\0';
}
Ну, и напоследок, вместо этого
Код:
result=(char*)realloc(result,0); // страсть к reallocam просто потрясающая
рекомендую
Код:
free( result );
А и ещё забыл. Перед первым вызовом convert не забудь вставить
Код:
result[0] = '\0';

Последний раз редактировалось Stilet; 30.03.2013 в 12:14.
FataLL вне форума Ответить с цитированием
Старый 30.03.2013, 12:07   #3
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Цитата:
result = strncpy( result, (char*) &d[c+1], 1 ); // & - большая разница
Ага, надо было разыменовывать. Так?
Цитата:
result = strncpy( result, (char*) &d[c], 1 ); // не надо 1 прибавлять
Все никак не свыкнусь с тем, что в Delphi строка начинается с 1 ячейки, а в С++ с нулевой.
Цитата:
В-третьих, ты постоянно копируешь текущую цифру в первую ячейку, что неправильно. Надо добавлять в конец строки.
Замечательно, вот тебе и конкатенация строк. Как тогда через эту функцию действительно объединять строки?
Цитата:
free( result );
Чем free лучше realloc(массив, 0)? Ведь и в том и в том случае в результате освободим память.
Если помог, проси поставить минус. Будь оригинален!
Rin вне форума Ответить с цитированием
Старый 30.03.2013, 14:01   #4
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

Ну, по коду тебе уже вроде всё отметили, добавлю по стилю.
если планируешь оставаться на уровне "студенческие поделки", то в принципе особо ничего менять не нужно.
если в будущем собираешься так или иначе связываться с IT, сразу же избавляйся от этого убожества в виде транслита.

cout<<"BBeDuTe B KaKy|-O CC nepeBoDuM\n";

Введите в каку??? LOL, хоть в шедевры заливай.

Rififi вне форума Ответить с цитированием
Старый 30.03.2013, 14:48   #5
FataLL
Форумчанин
 
Аватар для FataLL
 
Регистрация: 29.01.2013
Сообщений: 319
По умолчанию

Цитата:
Сообщение от Rin Посмотреть сообщение
Замечательно, вот тебе и конкатенация строк. Как тогда через эту функцию действительно объединять строки?
Читаешь rsdn? Молодец. Только вот ещё надо и внимательно читать. Там про какую функцию написано? А ты какую используешь?

Цитата:
Сообщение от Rin Посмотреть сообщение
Чем free лучше realloc(массив, 0)? Ведь и в том и в том случае в результате освободим память.
Код надо писать легко читаемый и понятный. У меня был знакомый, который везде и всюду использовал только switch(), даже когда можно было обойтись if(). Нравилось вот ему так. Но код выглядел ужасно... Рассматривай это просто как рекомендацию. Наверняка есть люди, которые швейцарскими часами забивают гвозди, потому что им так больше нравится...
FataLL вне форума Ответить с цитированием
Старый 30.03.2013, 21:59   #6
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Цитата:
если в будущем собираешься так или иначе связываться с IT, сразу же избавляйся от этого убожества в виде транслита.
Учту.
Цитата:
Читаешь rsdn? Молодец. Только вот ещё надо и внимательно читать. Там про какую функцию написано? А ты какую используешь?
Там про функции объединения вообще мало чего написано. Вот выдержка:
Цитата:
Для конкатенации следует использовать функции.

Есть две специальные функции:

char* strcat(char* dest, const char* source)
char* strncat(char* dest, const char* source, size_t size)
Эти функции добавляют к строке, на которую указывает dest, символы из строки source. Первая версия добавляет все символы до нуль-терминатора, вторая – максимум size символов. Результирующая строка завершается нуль-терминатором.
Написано, что добавляет максимум size символов. Я подразумевал, переводя на делфи - s1:=s1+s2[i]; или s1:=s1+copy(s2,i,1);. Но не тут то было. Функция перезаписывает символ в первой ячейке. В общем, надо дальше изучать, вникать, практиковаться.
Благодарю за ответы, отзывчивые незнакомцы.
Если помог, проси поставить минус. Будь оригинален!
Rin вне форума Ответить с цитированием
Старый 31.03.2013, 02:25   #7
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Каким способом (функцией, директивой компилятора) присвоить переменной другую переменную, а не указатель на эту переменную?
Захотел избавиться от одной строки таким способом:
Код:
void convert (__int64 chislo, int CC,char* &result)
{
  int c=chislo%CC;
  chislo=chislo/CC;
  int nLen;
  i++;
 nLen=i;
  result=(char*)realloc(result,sizeof(char)*i);
  if (chislo>0) convert(chislo,CC,result);
  //int nLen = strlen( result );
  result[ --i ] = d[c];
  result[ nLen ] = '\0';
}
При трассировке обнаруживается, что вместе с i уменьшается и nLen.
Если помог, проси поставить минус. Будь оригинален!

Последний раз редактировалось Rin; 31.03.2013 в 03:01.
Rin вне форума Ответить с цитированием
Старый 31.03.2013, 08:48   #8
FataLL
Форумчанин
 
Аватар для FataLL
 
Регистрация: 29.01.2013
Сообщений: 319
По умолчанию

Цитата:
Сообщение от Rin Посмотреть сообщение
Написано, что добавляет максимум size символов.
Для догадливых и умеющих читать, ещё раз, про какую функцию там "вообще мало что написано"? Ты знаешь, даже в дельфях, при каком угодно строе и диалекте strncat не то же самое, что strncpy.

Твой последний вопрос - вообще полная фигня. Ты нарушил всю логику, а причину ищешь совсем в другом месте. В переменной i, у тебя содержится количество цифр числа (если её не трогать). Начинаешь ты записывать с первого числа (самого старшего). Поэтому, уменьшая её на 1 каждый раз, ты тем самым по-очереди сокращаешь длину строки на 1 и в результате получаешь пустую строку. Всё работает правильно, как запрограммировал.

Ну, вот у тебя последовательные вызовы converta 1234 в 10-чное будут содержать { i = 2; nLen = 2; }, { i = 3; nLen = 3; }, { i = 4; nLen = 4; }, { i = 5; nLen = 5; }. Всё, значимая часть кончилась. И ты начинаешь сохранять старшую цифру числа. Куда? В result[4] = '1', а result[5] = '\0'; Теперь раскручивается стек:
- result[3] = '2', а result[4] = '\0';
- result[2] = '3', а result[3] = '\0';
- result[1] = '4', а result[2] = '\0';
Т.е., к моменту вывода результата, твой result содержит
- result[0] == '\0';
- result[1] == '\4';
- result[2] == '\0'; (затёртая '3')
- result[3] == '\0'; (затёртая '2')
- result[4] == '\0'; (затёртая '1')

Последний раз редактировалось FataLL; 31.03.2013 в 10:39. Причина: Плохо как-то сказал...
FataLL вне форума Ответить с цитированием
Старый 31.03.2013, 22:58   #9
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Цитата:
Теперь раскручивается стек
А про это я забыл. Теперь ясно из-за чего так.
Если помог, проси поставить минус. Будь оригинален!
Rin вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как исправить ошибку invalid conversion from const char* to char Ника К Помощь студентам 5 01.06.2012 00:13
С++ Преобразование const Char в const GUID Decoy2k Общие вопросы C/C++ 9 07.02.2012 14:02
невозможно преобразовать 'const char' в 'char triest Помощь студентам 1 10.12.2011 13:41
'unsigned char [512]' в 'const char *' frommars Visual C++ 8 02.07.2011 13:37
преобразование типов char-const char student101 Помощь студентам 8 01.12.2010 20:45