Уважаемый, rraassttaa, прошу прощения за резкость, 
НОНачнём с того, что в русском языке существуют знаки препинания, скажу больше — некоторые ретрограды их даже используют на письме, наивно считая, что предложения вида
вот что я наделал посмотрите скажите как сделать так чтобы он не выводил повторяющиеся символы по нескольку раз а 1 раз пример
 читать как минимум неприятно, а как максимум — невозможно, ибо не ясно, где кончается одна мысль и начинается другая (пресловутое "казнить нельзя помиловать").
Теперь о программе:Простите, но Вы в цикле используете одну и ту же переменную в качестве счётчика ВСЕХ символов. Более того, Вы её постоянно обнуляете внутри цикла при встрече каждого допустимого символа. Подобный (конечно, весьмаааа отдалённо, но всё-таки...) подход имеет право на существование (если Вы не_хотите/не_можете (по условию задания) использовать массив), но в этом случае алгоритм должен был бы выглядеть примерно следующим образом:
1. Создаётся набор допустимых символов: "abc...xyzABC...XYZ0...9"
2. Для КАЖДОГО символа из набора осуществляется подсчёт его вхождений в обрабатываемую строку. Если количество вхождений больше нуля, в выходную строку добавляем соответствующее сообщение.
Приблизительный код:
- Код: Выделить всё
 var 
  i, j, k:integer;
  Nabor:string; // Символы, количество которых необходимо подсчитать 
  InStr:string; // входная строка
  OutStr:string; // выходная строка
begin
OutStr:='';
for i:=1 to Length(Nabor) do begin
  k:=0;
  for j:=1 to Length(InStr) do
    if InStr[j]=Nabor[i] then inc(k);
  if k>0 then OutStr:=OutStr+Nabor[i]+' - '+IntToStr(k)+'; '
end;
end.
Набор уникальных символов формируется программистом (если Вы желаете исключить из учёта какие-то символы (пробел, знаки пунктуации и арифметических операций, прочие специальные символы) или программно из введенной строки приблизительно так:
- Код: Выделить всё
 var 
  i, j, k:integer;
  nabor:string; // набор уникальных символов
  InStr:string; // входная строка
begin
Nabor:='';
for i:=1 to Length(InStr) do begin
  k:=-1;
  for j:=1 to Length(Nabor) do
    if InStr[i]=Nabor[j] then begin
      k:=j;
      Break
    end;
  if k=-1 then Nabor:=Nabor+InStr[i]
end;
end.
Очевидно, что если использовать динамический массив для хранения счётчиков вхождения символов в строку, то скорость выполнения программы можно повысить:
- Код: Выделить всё
 var 
  i, j, k:integer;
  Counters:array of integer;
  nabor:string; // набор уникальных символов
  InStr:string; // входная строка
  OutStr:string; // выходная строка
begin
Nabor:='';
SetLength(Counters, 1);
for i:=1 to Length(InStr) do begin
  k:=-1;
  for j:=1 to Length(Nabor) do
    if InStr[i]=Nabor[j] then begin
      k:=j;
      Break
    end;
  if k=-1 then begin
    Nabor:=Nabor+InStr[i];
    k:=Length(Counters);
    SetLength(Counters, k+1);
    Counters[k]:=0
  end;
  inc(Counters[k])
end;
  OutStr:='';
  for i:=1 to Length(Nabor) do
    OutStr:=OutStr+Nabor[i]+' - '+IntTostr(Counters[i])+'; '
end.
P.S.В случае конкретно FreePascal, лучше использовать 
UTF8Length(s) вместо 
Length(s) и 
UTF8Copy(s,i,1) вместо 
s[i]. 
Если Вы не хотите различать строчные и прописные буквы, то сравнивать нужно не собственно символы, а символы, преобразованные к верхнему (
AnsiUpperCase(s) / 
UTF8UpperCase(s)) или нижнему 
(AnsiLowerCase(s) / 
UTF8LowerCase(s)) регистру. 
Для использования UTF8-функций, Вы должны подключить к своей программе модуль 
LCLProc.
С уважением, Алексей.