Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Программирование с нуля - это совсем просто! 51) Ответы-51


Информационный Канал Subscribe.Ru

 
Школа программирования

Программирование с нуля - это совсем просто!

51) Ответы-51

Основной блок ответов.

32. Сумма-разность 2-3 строк.

  #include <iostream.h>
  int a[27][72],x,y;
  int main()
  {
       for (x=0;x<27;x++){
            for (y=0;y<3;y++){ //Первые 3 строки
                 a[x][y]=random(101); //заполняем случайными
            }
            for (y=3;y<72;y+=2){ //Четные строки
                 a[x][y]=a[x][y-1]+a[x][y-2]+a[x][y-3]; //сумма 3-х предыдущих
            }
            for (y=4;y<72;y+=2){ //Нечетные строки
                 a[x][y]=a[x][y-2]-a[x][y-1]; //разность двух предыдущих
            }
       }
       return 0;
   }
  Екатерина

На Бейсике:

  function namedfunction()
  Dim odd As Boolean = True
  for I = 1 to 3
        for j = 1 to 27
        Mat(j, i) = Int(Rnd*100)
        Next j
  Next i

  for I = 4 to 72
        for j=1 to 27
        if odd then
            Mat(j, i) = mat(j-1, i) + mat(j-2, i) + mat(j-3, i)
            Odd = Not odd
        else
            Mat(j, i) = mat(j-2, i) - mat(j-1, i)
            Odd = not odd
        end if
        Next j
  Next i

  end function
                  
  Максим

На Паскале:

  program zad32;
  {$APPTYPE CONSOLE}
  uses SysUtils;
  var aarray[1..27,1..72] of integer;i,j,ninteger;
  begin
     for i=1 to 27 do
     for j=1 to 3 do
     a[i,j]=random(101);
     for i=1 to 27 do
     for j=4 to 72 do
      begin
       if j mod 2=0 then a[i,j]=a[i,j-1]+a[i,j-2]+a[i,j-3];
       if j mod 2=1 then a[i,j]=a[i,j-2]-a[i,j-1];
       writeln(a[i,j]);
      end;
      readln;
  end.

  Ярослав

N 33. Заполните матрицу случайными символами (тип char). Найдите столбец, где какой-то символ (для каждого столбца надо определить, какой он будет в этом столбце - какой будет встречаться в столбце чаще всего) встречается наибольшее число раз (если в столбце 3 символ "*" - самый частый, встретился 6 раз, а в столбце 2 символ "J" - самый частый, встретился 7 раз, то результатом будет 2-й столбец).

  Чуть не озверела, пока это упражнение доделала. Сначала никак не
  могла сообразить, сколько мне надо массивов. Потом запуталась в
  циклах совершенно, пришлось для самой себя комментарии писать,
  чтобы хоть как-то разобраться.
   
  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
       char a[10][10],ch,sim;
       int x,y,i,j,b[32],maxb[10],MAX,st;
   
       randomize();
       MAX=0;
       for (x=0;x<32;x++){ //Обнуление счетчика букв
            b[x]=0;
       }
       for (x=0;x<10;x++){ //Цикл по столбцу
            maxb[x]=0; //Обнуление максимального кол-ва букв в
  столбце
            for (y=0;y<10;y++){ //Цикл по элементам столбца
                 a[x][y]=random(256-224)+224; //Заполнение массива
  символами а-я
            }
       }
       for (x=0;x<10;x++){ //Цикл по столбцу
            for (i=0; i<32; i++){ //Цикл по символу
                 ch=i+224; //Текущее значение символа
                 for (y=0;y<10;y++){ //Проверка каждого элемента
  столбца
                      if (a[x][y]==ch){ //на соответствие текущему символу
                           b[i]++;
                      }
                 }
                 if (b[i]>maxb[x]){ //Подсчет максимального кол-ва
  одинаковых букв
                      maxb[x]=b[i];
                      if (MAX<maxb[x]){
                           MAX=maxb[x]; //Выбор самого максимального из всех
  максимальных :)
                           st=x; //Индекс столбца с максимумом
                           sim=ch; //Самый частый символ
                      }
                 }
            }
            for (j=0;j<32;j++){
                 b[j]=0;
            }
       }
       AnsiString str;
       str="Наибольшее количество (";
       str+=MAX;
       str+=")\nодинаковых букв - <";
       str+=sim;
       str+=">\nв ";
       str+=st+1;
       str+=" столбце" ;
       Label1->Caption=str;
  }
  Екатерина

На Паскале:

  program Project2;
  {$APPTYPE CONSOLE}
  uses
    SysUtils;
  var matr: array[1..70,1..10] of char;
       x,y,s,n : integer;
       max: array[1..10] of integer;
       maxch: array[1..10] of char;
       b: boolean;
  begin
      randomize;
     for x:=1 to 70 do
       for y:=1 to 10 do begin//for y
      s := random(254)+1;
     while (s=8)or(s=9)or(s=10)or(s=13) do s := random(254)+1;
      matr[x,y]:=chr(s);end;//for y
          for x:=1 to 70 do begin//for x
        writeln; writeln;
         for y:=1 to 10 do
         write(matr[x,y], ' ' ); end; //for x
           writeln;
             writeln;
          for y:=1 to 10 do begin//for y
          max[y]:=0;
          for x:=1 to 70 do begin//for x
          s:=1;n:=0;
          while s<=70 do begin //s
          if matr[s,y]=matr[x,y] then n:=n+1;s:=s+1; end; //s
          if n> max[y] then begin//if n
          max[y]:=n; maxch[y]:=matr[x,y]; end; //if n
          end; //for x
          end; //for y
          writeln;
        for s:=1 to 10 do write(max[s], ' ' );
        writeln;
          for s:=1 to 10 do write(maxch[s], ' ' );
         writeln;
              writeln;
            for s:=1 to 10 do begin// for s
                b:=true;
              for y:=1 to 10 do
          if max[s]<max[y] then b:=false;
              if b then begin //if b
      writeln( ' number stolbtsa= ' ,s, ' simvolov= ' ,max[s], ' simvol= ' ,maxch[s]);
       end; //if b
          end; //for s
           writeln;
        writeln( ' noka Bce... ' );readln;
    end.

  Алексей

35. Подстрока. Функция,находящая первое вхождение заданной подстроки в строку - номер символа

  //Функция, возвращает подстроку с позиции а длиной b
  AnsiString SubString (int a,int b,AnsiString str){
          AnsiString temp;
          for (int i=a;i<a+b;i++){
                  temp+=str[i];
          }
          return temp;
  }
   
  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
       AnsiString str, podstr;
          int slen,plen,i,j,n=0;
          str=Edit1->Text;
          podstr=Edit2->Text;
          Label1->Caption="";
          slen=str.Length(); //Длина строки
          plen=podstr.Length(); //Длина подстроки
          if (plen==0) return;
          for (i=1;i<=slen-plen+1;i++){ //Цикл по символам строки
                  if (SubString(i,plen,str)==podstr){
                          n=i;
                          break;
                  }
          }
          if (n==0) Label1->Caption="Не найдено!";
          else Label1->Caption="Позиция "+String(n);
  }
  Екатерина

На Паскале:

  function vps(s,ps:string): integer; // входящие и возвращаемый
  параметры
   var prov: string; // проверка
   var f: boolean;
   var i,j,dps,ds,ns: integer; // счётчики, длина строки, подстроки,
  номер символа
  begin
   ds:=length(s); // длина строки
   dps:=length(ps); // длина подстроки
   f:=false; // подстрока не найдена
   result:=0; // результат равен нулю
      for i:=1 to dps do // анализируемый символ подстроки
         begin

            for j:=1 to ds do // символы строки
                begin
                   if ps[i]=s[j] then // если символ подстроки равен символу
  строки, то
                       begin
                         prov:=copy(s,j,dps); // копируется часть строки, равная
  длине подстроки
                                               // начиная с номера совпавшего символа
  строки
                            if prov=ps then // если они равны, то
                                begin
                                  f:=true; // подстрока найдена
                                  ns:=j; // номер символа вхождения равен,
  номеру символа строки
                                  result:=ns; // возвращаемый результат равен
  этому номеру
                                end;
                       end;
                 if f=true then break; // если подстрока найдена в
  строке, остановить цикл
                end;
             end;
         end;

  procedure TForm1.Button11Click(Sender: TObject);
  var str,pstr,s:string;
  var nv:integer;
  begin
   str:=Edit1.Text;
   pstr:=Edit2.Text;

   nv:=vps(str,pstr);
   if nv<>0 then
      begin
     s:= ' Строка " ' +pstr+ ' " является подстрокой строки " ' +str+ ' " ' +#13;
     s:=s+ ' номер символа первого вхождения подстроки в строку -
  ' +IntToStr(nv);
      end
      else s:= ' Строка " ' +pstr+ ' " не является подстрокой строки " ' +str+ ' " ' ;
   Label32.Caption:=s;
   end;

  Лена

N 36. Написать функцию, заменяющую все вхождения одной подстроки на другую (могут быть разной длины!). Например, заменить каждый пробел на три звездочки. Или наоборот.

  Здесь я обнаружила, что переменная объявленная в цикле (for int i=0)
  в другом цикле уже не работает :(
   
  //Функция возвращает подстроку с позиции а длиной b
  AnsiString SubString (int a,int b,AnsiString str){
          AnsiString temp;
          for (int i=a;i<a+b;i++){
                  temp+=str[i];
          }
          return temp;
   
  }

  //---------------------------------------------------------------------------
   
  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
       AnsiString str,s1,s2,resalt;
       int len,len1,i;
       str=Edit1->Text;
       s1=Edit2->Text; //что меняем
       s2=Edit3->Text; //На что меняем
       len=str.Length();
       len1=s1.Length();
       if (len==0 || len1==0 || len1>len) return;
       for (i=1;i<=len-len1+1;i++){ //Цикл по символам строки
            if (SubString(i,len1,str)==s1){ //Если подстрока с i совпадает с
  заменяемым
                 resalt+=s2; //Заносим замену в результат
                 i+=len1-1; //Пропускаем то, что заменили
            }
            else resalt+=str[i]; //Иначе в результат заносим i-ый символ
       }
       for (i=len-len1+2;i<=len;i++){
            resalt+=str[i]; //Заносим оставшиеся символы в результат
       }
       Edit1->Text=resalt;
  }
  //---------------------------------------------------------------------------
  void __fastcall TForm1::Button2Click(TObject *Sender)
  {
       Close();
  }
   Екатерина

На Паскале:

   // Функция, заменяющая одну подстроку в строке на другую
   // входящие параметры и возвращаемый результат
  function zam(str,pstr ,pstr1:string): string; // строка, подстрока 1,
  подстрока 2
   // дополнительные переменные
  var str1,str2:string; // строка 1, строка 2
  var nv,dstr,dstr1,dpstr:integer; // номер вхождения подстроки
                                                 // длина строки, строки 1, подстроки 1

  begin

   dstr:=length(str); // длина строки
   dpstr:=length(pstr); // длина подстроки
   nv:=pos(pstr,str); // номер вхождения

       while (nv<>0) do // делать, пока можно найти подстроку
         begin
           str1:=str; // значение стрки 1
           str2:=str; // значение строки 2
           delete(str1,nv,(dstr-(nv-1))); // строка 1 равна части строки до
  найденной подстроки
                                          // удаляется часть строки, начиная от номера
  вхождения и до конца
           dstr1:=length(str1); // длина строки 1
           delete(str2,1,(dstr1+dpstr)); // строка 2 равна части строки после
  найденной подстроки
                                          // удаляется часть строки с начала до конца
  подстроки
           str:=str1+pstr1+str2; // новое значение строки равно
                                          // строка 1 + новая подстрока+ строка 2
           dstr:=length(str); // длина новой строки
           nv:=pos(pstr,str); // новый номер вхождения
        end;
     result:=str; // результат, значение изменённой строки
   end;

  procedure TForm1.Button12Click(Sender: TObject);
   var s,ps,ps1,st,s1:string;
   var np:integer;
   begin
    s:=Edit3.Text;
    s1:=s;
    ps:=Edit4.Text;
    ps1:=Edit5.Text;

    np:=pos(ps,s); // проверить, является ли подстрока подстрокой
  данной строки

   if np<>0 then // если да, то
    begin // вывод информации
       st:= ' Строка " ' +ps+ ' " является подстрокой строки " ' +s+ '
  " ' +#13+#13;
       s:=zam(s,ps,ps1); // вызов функции замены
       st:=st+ ' Было " ' +s1+ ' " ' + ' стало " ' +s+ ' " ' ; // вывод результата
     end
          // подстрока не является подстрокой данной строки, менять
  нечего
   else st:= ' Строка " ' +ps+ ' " является подстрокой строки " ' +s+ ' " ' ;

   Label37.Caption:=st;

  end;
  Лена

37. Посчитать цифры в числе

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
      AnsiString str,temp;
      int number[10],len,n=0;
      str=Edit1->Text;
      len=str.Length();
      for (int i=0;i<10;i++){
          number[i]=0;
          temp=IntToStr(i);
          for (int j=1;j<=len;j++){
              if (str[j]==temp[1]) number[i]++;
          }
      }
      str="Цифры в числе:\n";
          for (int i=0;i<10;i++){
            if (number[i]>0){
            n++;
            str+=String(number[i])+" - <"+String(i)+">\n";
          }
      }
      Label1->Caption=str+"Всего "+String(n)+" цифр";
  }
  //---------------------------------------------------------------------------
  void __fastcall TForm1::Button2Click(TObject *Sender)
  {
       Close();
  }
  Екатерина

На Паскале:

  procedure TForm1.Button13Click(Sender: TObject);

  var d,i,j,l:integer; // длина строки, счётчики, индекс символа
  var po, rs,s: string; //
  var sum:array[1..10] of integer; // массив цифр
  begin
  rs:=Edit6.Text;
  s:= ' Для записи этого числа были использованны: ' +#13;

  for l:=1 to 10 do sum[l]:=1; // сумма каждой цифры равна одному

  d:=length(rs); // длина числа-строки

    for i:=1 to d do // анализируемая цифра числа-строки
       begin
         if rs[i]<> ' , ' then // разделитель целой и дробной части не цифра
             begin
                l:=ord(rs[i])-ord( ' 0 ' )+1; // определить индекс цифры
                if sum[l]=1 then // если сумма больше одного, значит
                   begin // цифра уже анализировалась

                     for j:=i+1 to d do //цифра следующая за
  анализируемой
                        if rs[j]=rs[i] then sum[l]:=sum[l]+1; // если цифры
  одинаковые,
                                                              // сумма увеличивается

                           case (sum[l]mod 100) of // выбор падежного
  окончания
                             12,13,14: po:= ' раз ' ; // исключения
                               else
                                 begin
                                    case (sum[l] mod 10) of // окончание зависит от
  последней цифры
                                      2,3,4: po:= ' раза ' ;
                                      0,1,5..9: po:= ' раз ' ;
                                    end;
                                 end;
                            end;
                            //вывод результата
                      s:=s+ ' Цифра ' +rs[i]+ ' - ' +IntTostr(sum[l])+po+#13;
                   end;
             end;
        end;

   Label39.Caption:=s;
  end;
  Лена

38. Разделить строку по символам-разделителям

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
       AnsiString str,symb,resalt;
       int i,j,Len,len,x;
       str=Edit1->Text; //Строка
       symb=Edit2->Text; //Символы разделители
       Len=str.Length(); //Длина строки
       len=symb.Length(); //Длина строки символов
       ListBox1->Clear();
       for (i=1;i<=Len;i++){
            x=0;
            for( j=1;j<=len;j++){
                 if (str[i]==symb[j]){ //Если символ строки = символу
  разделителю
                      if (resalt!="") ListBox1->Items->Add(resalt); //Вывод не
  нулевой строки в список
                      resalt=""; //Обнуление строки результата
   
                 }
                 else x++; //Иначе увеличиваем счетчик проверенных
  символов
                 if (x==len) resalt+=str[i]; //Если не подошел ни один
  символ
            } //увеличиваем результат на один символ
  исходной строки
       }
       ListBox1->Items->Add(resalt);
  }
  //---------------------------------------------------------------------------
  void __fastcall TForm1::Button2Click(TObject *Sender)
  {
       Close();
  }
  //---------------------------------------------------------------------------
   Екатерина

На Паскале:

  unit Unit1;
  interface
  uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
  Forms,
    Dialogs, StdCtrls;
    var z:integer;
  type
    TForm1 = class(TForm)
      e1: TEdit;
      l1: TLabel;
      Label1: TLabel;
      e2: TEdit;
      b1: TButton;
      l2: TLabel;
      procedure b1Click(Sender: TObject);
    private
      { private declarations }
    public
      { public declarations }
    end;
  var
    Form1: TForm1;
  implementation
  {$R *.dfm}
  procedure TForm1.b1Click(Sender: TObject);
  var b:array[1..100] of boolean;
  i,n:integer;
  s,r : string;
  begin
  z:=length(e1.Text);
  l1.Caption:= ' ' ; l2.Caption:= ' ==>> ' ;
   s:=e1.Text;
   r:=e2.text;
   for i:=1 to z do b[i]:=false;
    for i:=1 to z do begin//for i
    for n:=1 to length(r) do
    if s[i]=r[n] then begin
    b[i]:=true;end;
    end; //for i
    for i:=1 to z do l1.Caption:=l1.Caption+booltostr(b[i]);
    for i:=1 to z do
    if b[i] then l2.Caption:=l2.Caption+^m else l2.Caption:=l2.Caption+s[i];
  end;

  Алексей

N 39. Дано целое число N. Проверить, является ли оно суммой своих делителей (которые тоже надо найти). 6 = 1+2+3.

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
       int N,sum=0;
       AnsiString str;
       str="Делители:";
       N=StrToInt(Edit1->Text);
       for (int i=1;i<N;i++){
            if( N%i==0){ //Если остаток от деления равен 0
                 sum+=i; //суммируем делители
                 str+=" "+String(i);
            }
       }
       if (sum==N) str+="\nСумма "+String(sum)+" равна делимому!";
       else str+="\nСумма "+String(sum)+" не равна делимому!";
       Label1->Caption=str;
  }
  Екатерина

На Паскале:

  procedure TForm1.Button14Click(Sender: TObject);
  var a,n,s,d: integer;
  var st:string;
   begin

   a:=StrToInt(Edit7.Text);

   n:=0; // начальный номер делителя
   s:=0; // начальная сумма делителя
   d:=1; // первый делитель
   while d<a do // делать, пока делитель не будет равен данному
  числу
       begin
         if (a mod d) =0 then // если остаток от деления равен нулю, то
            begin
              n:=n+1; // номер делителя
              st:=st+ ' делитель N ' +IntToStr(n)+ ' равен ' +IntToStr(d)+#13;
              s:=s+d; // сумма делителей
            end;

             d:=d+1; // делитель увеличивается на один
        end;
       st:=st+#13+#13;
       st:=st+ ' Сумма всех делителей равна ' +IntToStr(s)+#13+#13;

        // вывод результата
     if s=a then st:=st+ ' число ' +IntToStr(a)+ ' является суммой своих
  делителей '
            else st:=st+ ' число ' +IntToStr(a)+ ' не является суммой своих
  делителей ' ;
   Label41.Caption:=st;
   end;
  Лена

  program Project2;
   
  {$APPTYPE CONSOLE}
   
  uses
    SysUtils;
   
  var i,x,n: integer;
   
  begin
   writeln( ' BBeDuTe ' ,chr(230), ' e ' ,chr(171), ' oe ' ,chr(231), ' uc ' ,chr(171), ' o
  ' ,chr(3),chr(3),chr(3));
   readln(x);
   if x<0 then begin x:=-x;
   writeln( ' "x"berem po moduliu!!! ' );end;
   n:=0;write( ' Deliteli=> ' );
   for i:=1 to (x-1) do
   if x mod i=0 then begin;write(i, ' ' ); n:=n+i;end;
   writeln;
   writeln( ' Vashe chislo= ' ,x);
   writeln( ' Summa deliteley= ' ,n, ' npaBu ' ,chr(171), ' bHo? ' );
   if n=x then writeln( ' Kak BuDuTe - yavlyaetsya ' )
   else writeln( ' Kak BuDuTe - ne yavlyaetsya ' );
   readln;
   
  Алексей

Вот Надежда тоже придумала свой метод сортировки!

Что-то слышала про пузырьковый метод. Но придумала свой :) метод - вычисляем наименьшее (или наибольшее), меняем местами с первым элементом массива, затем то же самое с оставшимися элементами. Стала кодировать. Вложенный цикл надо делать. Что-то не работает. Полезла в книжку и наткнулась на свой:)) метод - он второй по простоте после пузырькового метода, наверно, во всех книжках есть. А с кодом я при помощи отладчика справилась - проверяла каждое действие, находила ошибки.

  procedure TForm1.Button1Click(Sender: TObject);
  var i, j, g, B, N,j1:Integer;
  m: array[1..10] of Integer;
  begin
  randomize;
  for i:=1 to 10 do
          m[i]:= random(50)+50;//случайные числа от 50 до 100
  //Вывести на экран массив
  for i:=1 to 5 do
          Label1.Caption:= Label1.Caption + IntToStr(m[i])+ ' , ' ;
  Label1.Caption:= Label1.Caption + ^M;
  for i:=6 to 10 do
          Label1.Caption:= Label1.Caption + IntToStr(m[i])+ ' , ' ;

  //Сортировка

  //Ищу наименьший
  for j:=1 to 10 do
  begin
      B:=100;
      if m[j]<B then
        begin
        B:=m[j];
        g:=j;
        for i:=j+1 to 10 do
             begin
             if m[i]<=B then
               begin
               B:=m[i];
               g:=i;
               end;
             end;
         end;
      //Меняю местами
      N:=m[j];
      m[j]:=B;
      m[g]:=N;
  end;

  //Вывести на экран массив
  for i:=1 to 5 do
          Label2.Caption:= Label2.Caption + IntToStr(m[i])+ ' , ' ;
  Label2.Caption:= Label2.Caption + ^M;
  for i:=6 to 10 do
          Label2.Caption:= Label2.Caption + IntToStr(m[i])+ ' , ' ;
  end;

На этом пока все. Таня на сайте begin.polubomu.ru готовит также ряд ответов, в рассылку по причине объема не вошедших.

Хочу также присоединиться к Олегу с выражением благодарности Тане, причём не только за то, что она взяла на себя труд разбираться в наших заморочках (а вникать в чужой код, на мой взгляд, раз в 10 труднее, чем с нуля написать собственный), за советы по оптимизации кода (можно сделать проще - гораздо ценнее, чем банальное выискивание ошибок, которые, в принципе, можно найти и самому), но и за то, что не отказывается вести разговор, пусть и касающийся программирования, но не относящийся непосредственно к тематике заданий.
Андрей


* И про матрицы вопрос такой. Это как то можно увидеть на экране ?
Алексей

Можно так- нажимаете в отдладчике, когда работа программы приостановлена, Ctrl+F7, показывается окно, в котором всегда можно посмотреть значение любой переменной. Вводите, типа a[5,7] и жмете enter. А если просто "a" ввести (имя переменной-массива), то он может показаться достаточно аккуратно, как массив в принципе... Можете еще в отладчике навести курсор на переменную-массив :)

* SpeedButton, вот ты пишешь(книгу читаю, потихоньку), у этой кнопки есть свойство Flat, ну это чтобы кнопка принимала плоский вид, я не нашла этого свойства в инспекторе, его там нет?, надо это свойство в самом коде указывать?

Там - в инспекторе - это свойство есть :)

* И еще насчет всплывающей подсказки. Оказывается она называется code completion.(то есть завершение кода, появляется после введения точки в названии объекта).

Да, можно в настройках - Tools -Editor Options на вкладке Code Insight задать, нужно ли автоматически предлагать такую подсказку, подсказывать количество и типы параметров функций, показывать значение выражений, на которых находится курсор (для режима отладки) и давать описание идентификатора, над которым курсор (у меня включены все, за исключением последней). А на вкладке Color в списке Color SpeedSetting можно выбрать одну из множества расцветок синтаксиса в редакторе. У меня стоит Classic. На этой же вкладке можно настроить и мелкие детали синтаксиса, как их показывать.

* Потом преобразовала это число в строку с фиксированным количеством знаков - FloatToStrF(d[x,y],ffFixed,4,2). Кстати "4" это всё-таки количество знаков, а два это то ,что после запятой.

Это для тех информация, кто спрашивал, как в Дельфи аккуратно выводить числа с плавающей запятой.

*   Узнал я как в MVC++.
  itoa(int,char,int) - переводит int в string
  ftoa - переводит float в string
  т.е.
  char s[]="";
  itoa(3,s,10);
  cout << s;
  3 - число, которое надо перевести в строку; s - строковая
  переменная, куда
  заносится результат; и, самое интересное, третье число (в данном
  случае 10) - система исчисления. Может быть 2 (двоичная), 16
  (шестнадцатеричная), и даже 3, 4 и т.д. Удобно, однако. :))
  Сергей

* Хотел сделать изменение шрифта в табличке(простой-жирный-и т д),не нашел как.

Шрифт меняется так - в свойстве Font есть подсвойство Style, там логические значения fsBold - сделать жирным, fsItalic - наклонно итд.

Применяется практически ко всем элементам управления, всех видов.

* Что-то у меня с записью в файл плохо получается. Дело в том, что когда я пишу

  for (i=1;i<=100;i++){
            str="Строка № "+IntToStr(i);
            fputs(str.c_str(),fout);
       }

все строки записываются в файле в одну строку.

Вот, например, когда я пыталась сделать 40 задание:

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
       FILE *fo;
       AnsiString str;
       int n,i;
       n=Memo1->Lines->Count;
       fo=fopen("memo.txt","wt");
       for (i=0;i<n;i++){
            str = Memo1->Lines->Strings[i];
            fputs(str.c_str(),fo);
       }
       fclose(fo);
  }
  //---------------------------------------------------------------------------
  void __fastcall TForm1::Button2Click(TObject *Sender)
  {
       FILE *fi;
       AnsiString str;
       char buf[100];
       fi=fopen("memo.txt","rt");
       while (!feof(fi)){
            fgets(buf,100,fi);
            str=buf;
            ListBox1->Items->Add(str);
       }
       fclose(fi);
  }

в список у меня загружаются все строчки из Memo подряд в одну строку.

Я попыталась исправить положение приписав к каждой строке перенос строки:

            str = Memo1->Lines->Strings[i]+"\n";

После этого строки в файл стали писаться по отдельности. Но вот с внесением строк в список дело обстоит хуже: во-первых после строки в списке появляется лишний символ (как раз перенос строки, я полагаю), а во-вторых последняя строка из файла заносится в список два раза. Причину этого явления я так и не смогла понять.

В Си для записи с переводом на новую строку действительно надо указывать дополнительно символ новой строки. При этом он и во вводимой поток попадает, это именно он и есть. Проще всего - явно его обрезать например. После того, как ввели:

fgets(buf,100,fi);

находим последий символ - для этого можно функцию числа символов в строке задействовать, strlen():

int n = strlen(buf);

после чего последим элементом вместо символа перевода строки записать ноль (символ конца строки):

buf[ n-1 ] = 0;

str=buf;
...

Кстати с этой программой у меня возникла неприятная проблема. Я сняла галочки в Project|Options|Packages с Build with runtime packages, и в Project|Options|Linker с Use dynamic RTL, прокомпилировала. Перезагрузилась в Win XP (Си у меня стоит в Win 98), посмотреть, будет ли работать. Ну вот, работать-то работает, но ScrollBar рисуется не по центру, и картинка обрезается снизу, а справа чуть ли не полкартинки обрезается. Почему так происходит, и как с этим бороться?

Есть такая проблема, по-моему это связано с тем, что в XP вид некоторых элементов управления настраивавется под текущие настройки системной темы. Поэтому для одинакового внешнего вида (если делать и для XP, и для 98), надо задействовать так называемые манифесты - текстовые (XML) файлы, в которых описываются конкретные настройки в зависимости от версии Windows. По-моему, в Дельфи 7 есть даже компонент такой, типа XP Manifecto, но сам не сталкивался никогда, не знаю.

Андрей прислал файл: windowsxp.res

Если его подключить к проекту перед компиляцией, то программа начинает использовать элементы управления (кнопки, диалоги) в стиле Windows XP. Возможно, это пригодится читателям рассылки.


Наконец, обещанное письмо Андрея по поводу ввода-вывода с помощью возможностей Си++.

В самом начале Вашей рассылки мы обсуждали преимущества языка C++ над остальными языками программирования (я его изучил в своё время самостоятельно, а первая любовь не ржавеет, хотя я сейчас пытаюсь продраться через дебри Паскаля) и где взять компилятор. С тех пор я только пару раз Вам писал, предпочитая присоединиться к молчащему большинству. Не потому, что не делаю домашних заданий, а потому, что о чём же писать, если всё ясно и понятно? Вам и без меня слишком много пишут, полагаю. :)
Но сейчас мы подошли к теме, которая в своё время вызвала у меня наибольшие затруднения. Это непосредственная работа с файлами. И связано это было с тем, что большинство учебников идёт Вашим путём (не сочтите это вмешательством в Ваши права владельца рассылки... это так... размышления вслух :)) и под флагом C++ приводит методы работы с файлами C, который действительно труден для освоения. Прежде всего из-за множества функций, в которых путаешься, и из-за необходимости работать с указателями. Конечно, стараниями Страусрупа C и C++ до сих пор рассматривают как один язык, но с появлением Standard C 99 и ANSI/ISO Standard C++ эти два языка благополучно разделились, и появилась возможность выбирать. Лично я выбрал C++, поскольку использование классов позволяет легко писать сложные программы, а я человек занятой... ;)
Мы уже с Вами обсуждали преимущества потокового ввода-вывода C++ над функциями ввода-вывода C. И как показывают мои наблюдения за C/C++ кодировщиками Вашей рассылки, практика подтверждает преимущества первого способа: народ предпочитает использовать именно потоковый вывод   (cin>>, cout<<), а не функции. В этом плане использование потоков при работе с файлами C++ также гораздо удобнее, нежели использование функций: можно объявить файловый поток (т.е. файловую переменную, точнее, объект класса fstream), связать его с конкретным именем файла, открыть/создать этот самый файл, установить режим обращения к нему и задать права доступа к нему пользователей... одной строкой!

Пример:

  #include <fstream.h> // Для доступа к классам файлового
  ввода-вывода
  #include <conio.h>
  //-------------------------------------------------------------
  int main()
  {
     fstream MyFile("C:\\tmp\\MyFile.txt", ios::app, 2);
     /* Объявили объект файлового ввода-вывода MyFile класса fstream,
     связали его с физическим файлом MyFile.txt, флагом ios::app
  указали,
     что файл открыт только для записи, причём добавление строк
     осуществляется в конец файла после уже имеющихся; аргумент
  access
     получил значение 2, что означает "скрытый файл" - теперь его
  враги не
     увидят! :) */
     if( MyFile)
     {
        // Что-то делаем...
        MyFile.close(); // а потом файл закрываем...
     }
     else
     {
        cout<<"Unable to open file!"<<endl;
        cout<<"Press any key to exit...";
        getch();
        return 1;
     }
     cout<<"Press any key to exit...";
     getch();
     return 0;
  }

Кстати, в классе fstream есть одна фишка, которая мне очень нравится: в его конструкторе есть функция-член bool fstream::is_open(); которая проверяет правильность открытия файла (который физически на диске может и не существовать, неправильно задан путь и т.д.). В принципе, можно записать и так if(MyFile.is_open()==true), но, поскольку в классах fstream (ввод-вывод), ofstream (запись), ifstream (считывание) эта функция-член вызывается автоматически (ещё одно преимущество C++), то достаточно написать if(MyFile): C++ язык для тех, кто не любит долго набирать с клавиатуры! :)
Кстати, наблюдение из практики: при компилировании вышеприведённого текста в 16-разрядных компиляторах (Turbo C++ 3.0) и выполнении программы в случае отсутствия физического файла по заданному пути выдаётся сообщение о невозможности открыть файл, а в случае 32-разрядных компиляторов (Visual C++, Borland C++ Builder) - файл создаётся. По-видимому, это связано с запретом на непосредственный доступ к жёсткому диску в ОС линии WinNT (я работаю в WinXP) программ под DOS.

Ещё одним достоинством класса fstream я считаю, что он поддерживает все типы C++, включая указатели, причём ввод в файл осуществляется стандартно, подобно   cout<< , а вывод из файла - с помощью функции-члена getline(char*, int MAXIMAL_LENGTH_OF_A_STRING);

Пример:

  #include <iostream.h>
  #include <fstream.h>
  #include <conio.h>;
  //-------------------------------------------------------------------
  int main()
  {
     ofstream fout("test.txt"); // Открываем файл для записи.
     fout<<"Now we ' re writing something: "<<100<<" "<<hex<<100<<"
  "<<(2+2)<<endl;
     //Запись в файл.
     fout.close();
     ifstream fin("test.txt"); // Открываем тот же файл для чтения.
     char sContent[500];
     fin.unsetf(ios::skipws); // Не пропускать пробелы.
     while( !fin.eof()) // До тех пор, пока файл не кончится...
     {
        fin.getline(sContent, 500); // выводим данные из файла в строку...
        cout<<sContent<<endl; // и смотрим, что же мы навводили...
     }
     fin.close();
     cout<<"Press any key to exit...";
     getch();
     return 0;
  }

Результат выполнения данной программы - появление на экране строк:
Now we're writing something:
100 64 4
Press any key to exit...

А если добавить, что класс fstream поддерживает неформатированный ввод-вывод, т.е. позволяет редактировать не только текстовые, но и бинарные файлы... Словом, я свой выбор сделал... :)

Только взгляните, какое богатство режимов обращения к файлам: ios::in - считывание, позиционирование в начало файла (или можно использовать класс ifstream - у него это по умолчанию) ios::out - запись поверх имеющихся, позиционирование в начало файла, стирание без предупреждения (или можно использовать класс ifstream - у него это по умолчанию)

Пример (пытался набросать почтовую программу, но не получилось, но всё же):

  void __fastcall TMainForm::FormActivate(TObject *Sender)
  {
          fstream smtp("smtp.cnf", ios::out | ios::in, 2);
          // Открываем файлы конфигурации...
          fstream pop("pop.cnf", ios::out | ios::in, 2);
          fstream port("port.cnf", ios::out | ios::in, 2);
          fstream user("user.cnf", ios::out | ios::in, 2);
          fstream password("password.cnf", ios::out | ios::in, 2);
          fstream from("from.cnf", ios::out | ios::in, 2);
  }

Здесь - считывание с начала файла, запись - поверх имеющейся, файлам присваивается атрибут "скрытый".

ios::ate - для записи и считывания. Запись поверх первоначальной, но позиционирование в конец файла
ios::app - только для записи. Добавление в конец файла после уже имеющейся.
ios::trunc - запись с предварительным стиранием предыдущей записи (можно позиционировать в любое место файла)
ios::nocreate - не открывать (не создавать) файл, если он ранее не существовал
ios::binary - бинарный (не текстовый) файл

Права доступа к файлу:
0 - свободный доступ (по умолчанию)
1 - только чтение
2 - скрытый файл
4 - системный файл
8 - архивный файл

Оставшаяся часть письма выйдет в подборке с решениями по заданиям с файлами.


Я тут подумал, что может быть некоторые задания из прошлого выпуска все же сложные достаточно. В том плане, что 44.1 пожалуй трудна, а искать решения по нумерологии многие ленятся :) Хотя те, что присланы, очень интересные.

Поэтому задание 44.1 объявляется необязательным (лучше сделать, конечно, там немало полезных идей придется применить, практика хорошая). Что касается нумерологии, 43-го, то вместо него кто хочет, может следующую задачу сделать:

43-b. Две армии случайной численностью N и M (N и M меньше 10000) бойцов ведут сражение. В каждый момент времени (один такт игры) каждый одиночный боец первой армии сражается с одиночным бойцом второй армии (один на один). Не принявшие участие бойцы армии, где солдат больше (им не с кем было сразиться), выбирают случайно также по одному врагу и проводят свои бои один на один. После этого ход (такт) заканчивается.

Война идет до полного уничтожения одной из сторон. Каждый боец характеризуется начальным запасом здоровья (целое = 100), вероятностью нанесения точного удара, силой этого удара и вероятностью защиты. Эти вероятности одинаковы для каждой из армий. Например, вероятность удара - 70% (целое 70, при проверке бросаем кубик со 100 гранями, меньше или равно 70 - попал), вероятность защиты - 30%. Сила удара может случайно колебаться от 1 до 30 единиц.

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

Моделируем процесс сражения до конца, численность армий и при желании кто кому какой силы удар нанес и кто защитился, выводим в протокол - например в список, или консольное окно.


(c) 2004-2005 Сергей Бобровский bobrovsky@russianenterprisesolutions.com

Школа программирования с нуля
Все предыдущие выпуски базового курса тут:
http://russianenterprisesolutions.com/sbo/

 

http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: comp.soft.prog.prognull
Отписаться

В избранное