{                                                                         }
{ Notas 2: Este programa lê um arquivo contendo notas de alunos no        }
{          formato abaixo e calcula as notas finais dos mesmos.           }
{                                                                         }
{ formato do arquivo: cada linha contém um nome e uma nota parcial, aonde }
{          o separador entre nome e nota é um espaço. Podem haver várias  }
{ notas parciais, e o arquivo NÃO está ordenado por nome.                 }
{                                                                         }
{ Sérgio Campos -- 07/2003                                                }
{                                                                         }

program notas2;

var nome_arquivo : String;
    arq		 : text;
    nome	 : String;
    nota	 : integer;
    i		 :  integer;

    { Estes vetores armazenarão todos os alunos e suas notas              }
    { a nota do aluno todos_nomes[i] é todas_notas[i]                     }
    { uma marca de fim de dados é usada: todas_notas[i] = -1 significa    }
    { que os valores válidos dos vetores vão de 1 a i-1.                  }
    todos_nomes: array [1..100] of String;
    todas_notas: array [1..100] of integer;
    

{ O procedimento le_linha le uma linha do arquivo de entrada e coloca o   }
{ seu conteúdo em duas variáveis, nome e nota. O nome é o primeiro valor  }
{ e consiste de uma string separada por um espaço da nota, que é inteira  }
procedure le_linha(var nome : String; var nota: integer);
var c	      : char;
begin
   { É necessário ler caracter por caracter e concatenar os caracteres    }
   { lidos na variável nome, uma vez que a leitura da string diretamente  }
   { leria também a nota como parte do nome                               }
   nome := '';
   read(arq, c);
   while c <> ' ' do begin     { quando achar um espaço para de ler o nome}
      nome := nome + c;        { concatena o último caracter lido em nome }
      read(arq, c);            { e lê o próximo.                          }
   end;
   readln(arq, nota);  { após ler o nome a nota pode ser lida diretamente }
end; { le_linha }

{ Dados um nome e uma nota, insere procura para saber se o nome já existe }
{ no vetor. Se existir, a nota existente em todas_notas é incrementada. Se}
{ não existir, insere vai inserir este par nome,nota na próxima posição   }
{ vazia das tabelas.                                                      }
procedure insere(nome : string; nota: integer);
var i :  integer;
begin
   { busca por este nome em todas as posições do vetor todos_nomes, mas   }
   { para se encontrar todas_notas[i] = -1, que é a marca de fim de dados }
   i := 1;
   while (todas_notas[i] <> -1) and (todos_nomes[i] <> nome) do
      i := i + 1;

   if (todas_notas[i] = -1) then begin
      { Significa que o nome não foi achado, portanto temos que inserir   }
      todos_nomes[i] := nome;
      todas_notas[i] := nota;
      todas_notas[i+1] := -1;    { insere nova marca de fim de dados      }
                              { observação: tem que checar por i < 100!!! }
   end else begin
      { Achou o nome, é só modificar a nota                               }
      todas_notas[i] := todas_notas[i] + nota;
   end;
end; { insere }
   

begin
   { Determina o nome do arquivo (a partir da linha de comando), e o abre }
   nome_arquivo := Paramstr(1);
   assign(arq, nome_arquivo);
   reset(arq);
   todas_notas[1] := -1;          { insere marca dizendo que não há dados }
   
   while not eof(arq) do begin
      le_linha(nome, nota);     { le uma linha do arquivo                 }

      insere(nome, nota);
   end;

   i := 1;
   while (todas_notas[i] <> -1) do begin
      writeln('Aluno: ', todos_nomes[i], ' nota: ', todas_notas[i]);
      i := i + 1;
   end;

   writeln('the end!');
   
end.


