2015-04-11 2 views
2

У меня есть строка со словом в начале (что я хочу игнорировать), а затем некоторые числа, которые я хочу сохранить в массиве. Не все, только некоторые.Почему sscanf падает при добавлении дополнительных переменных?

Я использую 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; 

тогда я получаю сообщение об ошибке выполнения: «Проект MyProject выбросил исключение из класса„ External: SIGSEGV“по адресу 82E37E1».

Любые идеи о том, что может пойти не так? Большое спасибо.

Я использую lazarus 1.2.4 с fpc 2.6.4 в Linux Mint 17.1 32bits.

EDIT: Как было предложено Abelisto, вопрос был о s, я изменил его от PChar в строку и инициализировать его с некоторыми пробелами и все работает отлично. Код считывает строки в TMemo для получения данных, а затем делает таблицу (в 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. Спасибо всем за помощь!

+0

Рад видеть, что вы разрешили проблему. Кстати, это «хак» в коде, где вы инициализируете '' 'переменную фиксированным количеством пробелов. Если вам действительно не нужен первый текст во входной строке, просто удалите сначала «текстовое» значение из используемой вами строки, например 'dataline: = Copy (dataline, Pos ('', dataline) + 1, Length (dataline)); 'и удалить' @ s' из 'sscanf' – Abelisto

ответ

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;.

BTW: Win7, FPC 3.1.1 32 бит.

+0

Нет, это не сработает без дополнительной тонкой настройки. Когда я 'ideone'-это как« паскаль (fpc) ​​», например, в https://ideone.com/z9Q8m1, тогда результат« _On необработанное исключение произошло ...: EAccessViolation: нарушение доступа ... » – xmojmr

+0

@xmojmr Не используйте некоторые веб-файлы s..tuff вместо собственного настольного приложения. Никто не отвечает за используемый компилятор. – Abelisto

+1

@xmojmr Я просто тестирую этот код с FPC 2.6.4 и да, он бросает SIGSEGV. Но, как я упоминал выше, я использую FPC 3.1.1. – Abelisto