为什么 sscanf 在添加更多变量时会崩溃?
Why sscanf crashes when adding more variables?
我有一个字符串,开头有一个单词(我想忽略),然后是一些我想存储在数组中的数字。不是全部,只是一些。
我是这样使用sscanf的
var
x: integer;
y: array[0..19] of integer;
s: pchar;
begin
...
sscanf(dataline, "%s %d %d %d %d %d %d %d %d %d %d %d",
[s, @x, @y[0], @y[1], @y[2], @y[3], @y[4],
@y[5], @y[6], @y[7], @y[8], @y[9]]);
...
end;
没关系。但如果我只想再读一本
var
x: integer;
y: array[0..19] of integer;
s: pchar;
begin
...
sscanf(dataline, "%s %d %d %d %d %d %d %d %d %d %d %d %d",
[s, @x, @y[0], @y[1], @y[2], @y[3], @y[4],
@y[5], @y[6], @y[7], @y[8], @y[9], @y[10]]);
...
end;
然后我收到运行时错误:"The project myproject has thrown an exception of class 'External: SIGSEGV'. at address 82E37E1"。
有什么可能出错的想法吗?非常感谢。
我在 Linux Mint 17.1 32 位中使用带有 fpc 2.6.4 的 lazarus 1.2.4。
编辑:正如 Abelisto 所建议的,问题是关于 s
,我将它从 PChar 更改为 String 并用一些空格对其进行了初始化,一切正常。代码读取 TMemo 中的行以获取数据,然后使 table(在 TListView 中)添加值,然后添加最小值、平均值和最大值。请注意,1023 是可能的最大值。
procedure TfMain.bGetDataClick(Sender: TObject);
const
dataPoints = 20;
var
it: TListItem;
n, i, x, avg, min, max: integer;
y: array[0 .. dataPoints - 1] of integer;
dataLine: string;
s: string = ' ';
begin
datalist.BeginUpdate;
datalist.Clear;
n := -1;
while n < cSerIn.Lines.Count do
begin
Inc(n);
dataLine := cSerIn.Lines[n];
sscanf(dataLine, '%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d',
[@s, @x, @y[0], @y[1], @y[2], @y[3], @y[4],
@y[5], @y[6], @y[7], @y[8], @y[9],
@y[10], @y[11], @y[12], @y[13], @y[14],
@y[15], @y[16], @y[17], @y[18], @y[19]]);
it := dataList.Items.Add;
it.Caption := IntToStr(x);
avg := 0;
min := 1023;
max := 0;
for i := 0 to dataPoints-1 do
begin
it.SubItems.Add(IntToStr(y[i]));
avg += y[i];
if y[i] < min then min := y[i];
if y[i] > max then max := y[i];
end;
avg := avg div dataPoints;
it.SubItems.Insert(0, IntToStr(max));
it.SubItems.Insert(0, IntToStr(avg));
it.SubItems.Insert(0, IntToStr(min));
end;
datalist.EndUpdate;
end;
我也发现我的fpc版本是2.6.4,不是2.6.0。谢谢大家的帮助!
program project1;
uses
sysutils;
const
CArrCnt = 19;
var
x: integer;
y: array[0..CArrCnt] of integer;
s: string; // changes here
dataline: string;
i: Integer;
begin
dataline := 'aaa 123 0 1 2 3 4 5 6 7 8 9 10 11';
s := ' '; // changes here
sscanf(dataline, '%s %d %d %d %d %d %d %d %d %d %d %d %d %d',
[@s, @x, @y[0], @y[1], @y[2], @y[3], @y[4], @y[5],
@y[6], @y[7], @y[8], @y[9], @y[10], @y[11]]);
WriteLn(s);
Writeln(x);
for i := 0 to CArrCnt do
WriteLn(y[i]);
ReadLn;
end.
工作正常。
你必须展示更多的程序代码。例如,我们不知道 s: pchar;
的内存是否已分配。
顺便说一句:Win7,FPC 3.1.1 32 位。
我有一个字符串,开头有一个单词(我想忽略),然后是一些我想存储在数组中的数字。不是全部,只是一些。
我是这样使用sscanf的
var
x: integer;
y: array[0..19] of integer;
s: pchar;
begin
...
sscanf(dataline, "%s %d %d %d %d %d %d %d %d %d %d %d",
[s, @x, @y[0], @y[1], @y[2], @y[3], @y[4],
@y[5], @y[6], @y[7], @y[8], @y[9]]);
...
end;
没关系。但如果我只想再读一本
var
x: integer;
y: array[0..19] of integer;
s: pchar;
begin
...
sscanf(dataline, "%s %d %d %d %d %d %d %d %d %d %d %d %d",
[s, @x, @y[0], @y[1], @y[2], @y[3], @y[4],
@y[5], @y[6], @y[7], @y[8], @y[9], @y[10]]);
...
end;
然后我收到运行时错误:"The project myproject has thrown an exception of class 'External: SIGSEGV'. at address 82E37E1"。
有什么可能出错的想法吗?非常感谢。
我在 Linux Mint 17.1 32 位中使用带有 fpc 2.6.4 的 lazarus 1.2.4。
编辑:正如 Abelisto 所建议的,问题是关于 s
,我将它从 PChar 更改为 String 并用一些空格对其进行了初始化,一切正常。代码读取 TMemo 中的行以获取数据,然后使 table(在 TListView 中)添加值,然后添加最小值、平均值和最大值。请注意,1023 是可能的最大值。
procedure TfMain.bGetDataClick(Sender: TObject);
const
dataPoints = 20;
var
it: TListItem;
n, i, x, avg, min, max: integer;
y: array[0 .. dataPoints - 1] of integer;
dataLine: string;
s: string = ' ';
begin
datalist.BeginUpdate;
datalist.Clear;
n := -1;
while n < cSerIn.Lines.Count do
begin
Inc(n);
dataLine := cSerIn.Lines[n];
sscanf(dataLine, '%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d',
[@s, @x, @y[0], @y[1], @y[2], @y[3], @y[4],
@y[5], @y[6], @y[7], @y[8], @y[9],
@y[10], @y[11], @y[12], @y[13], @y[14],
@y[15], @y[16], @y[17], @y[18], @y[19]]);
it := dataList.Items.Add;
it.Caption := IntToStr(x);
avg := 0;
min := 1023;
max := 0;
for i := 0 to dataPoints-1 do
begin
it.SubItems.Add(IntToStr(y[i]));
avg += y[i];
if y[i] < min then min := y[i];
if y[i] > max then max := y[i];
end;
avg := avg div dataPoints;
it.SubItems.Insert(0, IntToStr(max));
it.SubItems.Insert(0, IntToStr(avg));
it.SubItems.Insert(0, IntToStr(min));
end;
datalist.EndUpdate;
end;
我也发现我的fpc版本是2.6.4,不是2.6.0。谢谢大家的帮助!
program project1;
uses
sysutils;
const
CArrCnt = 19;
var
x: integer;
y: array[0..CArrCnt] of integer;
s: string; // changes here
dataline: string;
i: Integer;
begin
dataline := 'aaa 123 0 1 2 3 4 5 6 7 8 9 10 11';
s := ' '; // changes here
sscanf(dataline, '%s %d %d %d %d %d %d %d %d %d %d %d %d %d',
[@s, @x, @y[0], @y[1], @y[2], @y[3], @y[4], @y[5],
@y[6], @y[7], @y[8], @y[9], @y[10], @y[11]]);
WriteLn(s);
Writeln(x);
for i := 0 to CArrCnt do
WriteLn(y[i]);
ReadLn;
end.
工作正常。
你必须展示更多的程序代码。例如,我们不知道 s: pchar;
的内存是否已分配。
顺便说一句:Win7,FPC 3.1.1 32 位。