Hi, I'm trying to run the simple included program, but I receive that error: Internal error: string capacity cannot be negative. I have noticed that the problem start on readln inside the loop. Is there a way to overcome that? Window95, gpc version 2.53.
Thanks for your help. Paolo Cortelli
program txt2rec; type rmaterie = record m_materia:string[18]; m_esclude:string[78]; m_len: integer; m_esc: array[1..5] of integer; end; tmaterie = array[0..0] of rmaterie; pmaterie = ^tmaterie;
var k,len_m: integer; materie: pmaterie; f: text;
procedure p_mat(fl:string); begin assign(f,fl); reset(f); readln(f,len_m); getmem(materie,sizeof(rmaterie)*len_m); for k := 1 to len_m do readln(f,materie^[k].m_materia,materie^[k].m_esclude); close(f); freemem(materie,sizeof(rmaterie)*len_m); end;
begin p_mat('materie.txt'); end.
{ This is the contents of MATERIE.TXT
36 BIOLOGIA \LAB.BIOLOG CALCOLO \LAB.CALCOLO CHIMICA \LAB.CHIMICA }
Cortelli Paolo wrote:
Hi, I'm trying to run the simple included program, but I receive that error: Internal error: string capacity cannot be negative. I have noticed that the problem start on readln inside the loop. Is there a way to overcome that? Window95, gpc version 2.53.
Thanks for your help. Paolo Cortelli
program txt2rec; type rmaterie = record m_materia:string[18]; m_esclude:string[78]; m_len: integer; m_esc: array[1..5] of integer; end; tmaterie = array[0..0] of rmaterie; pmaterie = ^tmaterie;
var k,len_m: integer; materie: pmaterie; f: text;
procedure p_mat(fl:string); begin assign(f,fl); reset(f); readln(f,len_m); getmem(materie,sizeof(rmaterie)*len_m); for k := 1 to len_m do readln(f,materie^[k].m_materia,materie^[k].m_esclude); close(f); freemem(materie,sizeof(rmaterie)*len_m); end;
begin p_mat('materie.txt'); end.
{ This is the contents of MATERIE.TXT
36
BIOLOGIA \LAB.BIOLOG CALCOLO \LAB.CALCOLO CHIMICA \LAB.CHIMICA }
The problem is the use of getmem: it reserves the memory but not initializes it: the capacity fields of the strings are undefined and happen to have a negative value. This program was probably working with BP because strings in BP have no Capacity field, only a length field. This problem can be solved in several ways. - ugliest and closest to BP, initialize manually the capacity fields inside the k loop. - dirty and BP compatible: use new instead of getmem for allocating records: the fields are initialized automatically. You could declare tmaterie as an array of pointers ^rmaterie, allocate the array of pointers materie^ with getmem, allocate each record within the k loop by new(materie^[k]) and use the syntax materie^[k]^.m_materia in the readln. - clean and totally BP incompatible. Learn that gpc is not a mere BP clone, it is _much better_ . All this dirty programming is an ugly way to circumvent in BP the absence of variable length array with a C-style programming. Gpc gives a clean way to solve this problem with schemata of Extended Pascal. Read the corresponding section of the gpc doc and try the following:
program txt2rec; type rmaterie = record m_materia:string[18]; m_esclude:string[78]; m_len: integer; m_esc: array[1..5] of integer; end; tmaterie(n:integer) = array[1..n] of rmaterie; pmaterie=^tmaterie; var k,len_m: integer; materie: pmaterie; f: text;
procedure p_mat(fl:string); begin assign(f,fl); reset(f); readln(f,len_m); new(materie,len_m); for k := 1 to len_m do readln(f,materie^[k].m_materia,materie^[k].m_esclude); close(f); dispose(materie); end;
begin p_mat('materie.txt'); end.
See: tmaterie is now a schemata of variable length ...
Maurice