разобрать секцию из ini файла

Только для тех, кто пишет плагины под Total Commander. Обмен опытом, решение проблем.

Модераторы: d-view, Моторокер, Avada, CaptainFlint, Nik

Worros
Сообщения: 1123
Зарегистрирован: Пт янв 19, 2007 18:46

Сообщение Worros »

У меня проблема
Вот такой код

Код: Выделить всё

char mybuffer[5];
char * toinistring;
toinistring=(char*) malloc(128);

GetWindowRect(GetParent(ListWin), &rcClient);

strcpy(toinistring,"top=");
_itoa(rcClient.top,mybuffer,10);
strcat(toinistring,mybuffer);
strcat(toinistring,"\0");
strcat(toinistring,"\r");
strcat(toinistring,"bottom=");
_itoa(rcClient.bottom,mybuffer,10);
strcat(toinistring,mybuffer);
strcat(toinistring,"\0");
strcat(toinistring,"\r");
strcat(toinistring,"left=");
_itoa(rcClient.left,mybuffer,10);
strcat(toinistring,mybuffer);
strcat(toinistring,"\0");
strcat(toinistring,"\r");
strcat(toinistring,"right=");
_itoa(rcClient.right,mybuffer,10);
strcat(toinistring,mybuffer);
strcat(toinistring,"\n");
				
WritePrivateProfileSection("MplayerPosition",toinistring,IniFileName);
free(toinistring);
по непонятной мне причине пишет в конец ini-файла мусор.

В чем моя ошибка? Как выглядит правильный вариант?
VadiMGP
Сообщения: 1625
Зарегистрирован: Ср мар 21, 2007 20:58

Сообщение VadiMGP »

Навскидку сразу три ошибки.
1. Нули в конце строк
strcat(toinistring,"\0");
Ты имел в виду добавить ноль в конец строки, но это так не работает. Функция strcat добавляет ДО первого ноля. То есть в своем случае - ничего.

2. Паразитные символы
strcat(toinistring,"\r");
strcat(toinistring,"\n");
Этого быть не должно.

3. Буфер должен заканчиваться двойным нулем. В конце надо добавить еще один ноль.
VadiMGP
Сообщения: 1625
Зарегистрирован: Ср мар 21, 2007 20:58

Сообщение VadiMGP »

Да и вообще я бы писал по другому, типа такого

Код: Выделить всё

	char * toinistring;
	int n,p=0;

	toinistring=calloc(1,128);

	n=sprintf(toinistring+p,"top=%d",rcClient.top);
	p+=n+1;
	n=sprintf(toinistring+p,"bottom=%d",rcClient.bottom);
	p+=n+1;
	n=sprintf(toinistring+p,"left=%d",rcClient.left);
	p+=n+1;
	n=sprintf(toinistring+p,"right=%d",rcClient.right);
	
	WritePrivateProfileSection("MplayerPosition",toinistring,IniFileName);
	free(toinistring);
Worros
Сообщения: 1123
Зарегистрирован: Пт янв 19, 2007 18:46

Сообщение Worros »

VadiMGP писал(а):Да и вообще я бы писал по другому, типа такого
Скопипастил себе в проект вместо того, что я приводил, всё равно мусорит :shock:
Единственное, что я изменил в копипасте, это вернул строчку toinistring=(char*) malloc(128); т.к. на calloc у меня компилятор ругнулся
VS2003
VadiMGP
Сообщения: 1625
Зарегистрирован: Ср мар 21, 2007 20:58

Сообщение VadiMGP »

Worros писал(а):Единственное, что я изменил в копипасте, это вернул строчку toinistring=(char*) malloc(128);
Вот и получил плюшку. Я же не с бухты-барахты написал calloc. А потому что он сразу инициализирует выделенную память нулями. А ты вернул, вот и остался с мусором в памяти. Обнулять надо.
Worros
Сообщения: 1123
Зарегистрирован: Пт янв 19, 2007 18:46

Сообщение Worros »

Помогло, большое спасибо!
VadiMGP
Сообщения: 1625
Зарегистрирован: Ср мар 21, 2007 20:58

Сообщение VadiMGP »

В принципе можно и покрасивше . Даже и malloc подойдет. :D

Код: Выделить всё

	char * toinistring,*ptr;

	ptr=toinistring=(char*) malloc(128);

	ptr+=sprintf(ptr,"top=%d",rcClient.top)+1;
	ptr+=sprintf(ptr,"bottom=%d",rcClient.bottom)+1;
	ptr+=sprintf(ptr,"left=%d",rcClient.left)+1;
	ptr+=sprintf(ptr,"right=%d",rcClient.right)+1;
	*ptr=0;
	
	WritePrivateProfileSection("MplayerPosition",toinistring,IniFileName);
	free(toinistring);
Worros
Сообщения: 1123
Зарегистрирован: Пт янв 19, 2007 18:46

Сообщение Worros »

А второй вариант не ест памяти на 128 чаров больше?

И ptr тогда тоже освобождать надо?
VadiMGP
Сообщения: 1625
Зарегистрирован: Ср мар 21, 2007 20:58

Сообщение VadiMGP »

Нет, никакой дополнительной памяти никто не ест и, соответственно, освобождать тоже не надо.
Worros
Сообщения: 1123
Зарегистрирован: Пт янв 19, 2007 18:46

Сообщение Worros »

Угу, дошло. Две ссылки на одну и ту же область памяти. Туплю :(
Спасибо.
VadiMGP
Сообщения: 1625
Зарегистрирован: Ср мар 21, 2007 20:58

Сообщение VadiMGP »

Кстати, хотел спросить - а зачем вообще динамически память выделять? Не проще будет сразу написать

Код: Выделить всё

char toinistring[128],*ptr=toinistring;
Зачем сыр-бор с выделением и освобождением?
Worros
Сообщения: 1123
Зарегистрирован: Пт янв 19, 2007 18:46

Сообщение Worros »

По неопытности. Погорячился :)

Вообще-то был не доведенный до ума замысел не выделять строку больше необходимой, но это, видимо, не стоит накладных расходов на выделение/освобождение памяти.
VadiMGP
Сообщения: 1625
Зарегистрирован: Ср мар 21, 2007 20:58

Сообщение VadiMGP »

Если ты, хотя бы примерно, знаешь сколько нужно (в разумных пределах, конечно, не мегабайты) то статическое распределение выгоднее.
Ответить