Ir ao conteúdo
  • Cadastre-se

Codigo em pascal para ler caracteres em linha


SuperBond

Posts recomendados

Eu preciso criar um código em Pascal que leia números de um arquivo do tipo texto. Só que essa leitura teria que ser em linha ao invés de ser em coluna, e algarismo por algarismo. Por exemplo, no arquivo tem o numero 8345. Preciso que ele identifique um por um e apresente na tela:

 

8

3

4

 

então ele leria em linha e não em coluna. Como eu poderia fazer isso?

Link para o comentário
Compartilhar em outros sites

@SuperBond

 

Eu preciso criar um código em Pascal que leia números de um arquivo do tipo texto. Só que essa leitura teria que ser em linha ao invés de ser em coluna, e algarismo por algarismo. Por exemplo, no arquivo tem o numero 8345. Preciso que ele identifique um por um e apresente na tela:

 

8

3

4

 

então ele leria em linha e não em coluna. Como eu poderia fazer isso?

 

 

Você poderia usar ReadLn para fazer a leitura de cada linha do arquivo para uma variável do tipo string. Depois, basta percorrer essa string e ir imprimindo caractere por caractere.

 

 

 

LNW

Link para o comentário
Compartilhar em outros sites

Em 15/02/2014 às 23:08, LNW disse:

@SuperBond

 

 

 

Você poderia usar ReadLn para fazer a leitura de cada linha do arquivo para uma variável do tipo string. Depois, basta percorrer essa string e ir imprimindo caractere por caractere.

 

 

 

LNW

 

Fiz um pequeno codigo que lê de um arquivo e imprime na tela. Esse código nao separa os algarismos.

Só não entendi como percorrer a string e ir imprimindo um por um.

program SOSUB;
var 
  SOSUB:text;
  NUM  :string[50];
begin
assign(SOSUB, 'SOSUB.txt');
reset(SOSUB);
readln(SOSUB, NUM);
writeln(NUM);
close(SOSUB);r
eadln;
end.
Link para o comentário
Compartilhar em outros sites

@SuperBond

 

Em 15/02/2014 às 00:42, SuperBond disse:
 
 

Fiz um pequeno codigo que lê de um arquivo e imprime na tela. Esse código nao separa os algarismos.

Só não entendi como percorrer a string e ir imprimindo um por um.

 

Basta usar um laço de repetição para ler cada caractere da string através do seu índice. Esse índice vai variar de 1 até o tamanho da string lida.

program foo;
var
  SOSUB: Text;
  NUM: string[50];
  i: Integer;
begin
assign(SOSUB, 'SOSUB.txt');
reset(SOSUB);
readln(SOSUB, NUM);
For i := 1 To Length(NUM) do
  writeln(NUM[i]);
close(SOSUB);
readln;
end.

LNW

Link para o comentário
Compartilhar em outros sites

Perfeito LNW.

Eu não conhecia essa sintaxe to length. Eu tinha tentado criar um loop para ler algarismo por algarismo só que sem to length, não funcionou.

Valeu!

UPDATE

Caro, o to length só serve pra string, não é? Tentei fazer somar algum numero a cada algarismo lido, mas não funciona, acho que porque é lido como string. Tem algum comando que faça o mesmo que o to length só que para integer?

Link para o comentário
Compartilhar em outros sites

@SuperBond

 

 

Caro, o to length só serve pra string, não é? Tentei fazer somar algum numero a cada algarismo lido, mas não funciona, acho que porque é lido como string. Tem algum comando que faça o mesmo que o to length só que para integer?

 

 

 

Precisaria converter o caractere representando um numeral para inteiro. Poderia usar Val: http://www.freepascal.org/docs-html/rtl/system/val.html

 

 

Depende do que se quer fazer ao certo. Está muito vago.

 

 

 

LNW

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Olá.

 

Perfeito LNW.
Eu não conhecia essa sintaxe to length. Eu tinha tentado criar um loop para ler algarismo por algarismo só que sem to length, não funcionou.
Valeu!

UPDATE
Caro, o to length só serve pra string, não é? Tentei fazer somar algum numero a cada algarismo lido, mas não funciona, acho que porque é lido como string. Tem algum comando que faça o mesmo que o to length só que para integer?

O length() serve basicamente para retornar o "tamanho de strings ou de arrays" e só!. Não é ela que "separa os caracteres", ou seja, como a quantidade de caracteres, por linha, no arquivo pode variar (de 0 a 255, se não me engano), logo não ia dar certo especifigar um valor no for... Se fosse fixo, por exemplo com 4. O for poderia ficar assim:

for i := 1 to 4 do  writeln(NUM[i]);

Entendeu?

 

O length() serve somente para verificar o tamanho, e assim servindo para auxiliar a percorrer numa quantidade certa de vezes.


 

Description

Length returns the length of the string or array S, which is limited to 255 for shortstrings. If the string S is empty, 0 is returned.

Note: The length of the string S is stored in S[0] for shortstrings only. The Length function should always be used on ansistrings and widestrings.

For dynamical or statical arrays, the function returns the number of elements in the array.

Length also supports arguments of type PCharand PWideChar, in which case it is identical to the StrLen and WStrLen functions, respectively. In this case, the function actually calculates the length of the null-terminated string, and its execution time is proportional to the string length because the terminating null character is searched through a linear scan.

 

Fonte: http://www.freepascal.org/docs-html/rtl/system/length.html

 

Obs.: se não conseguir entender em inglês, vide link com tradução AQUI.

 

 

 

 

Precisaria converter o caractere representando um numeral para inteiro. Poderia usar Val: http://www.freepascal.org/docs-html/rtl/system/val.html

LNW

Além dessa forma citada por LNW, você pode também já ler como numérico, "basta" mudar de "NUM: string[50];" para "NUM: integer", por exemplo.

Obs.: Se tiver algum caractere não numérico (uma letra por exemplo), o programa vai travar... :D. (mas isso também é contornável).

No aguado.

Link para o comentário
Compartilhar em outros sites

Olha, eu resolvi de uma forma mais complexa, porém é onde meu conhecimento alcança  :blush:

program SOSUB;
var
  SOSUB: Text;
  i, n1, n2, n3:integer;
  NUM:array[1..10] of integer;
begin
assign(SOSUB, 'SOSUB.txt');
reset(SOSUB);
for i:=1 to 2 do
  begin
    readln(SOSUB, NUM[i]);
    if (NUM[i]<100) then
      begin
        n1:=0;
        n2:=NUM[i] div 10;
        n3:=NUM[i]-(n2*10);
        writeln(n1);
        writeln(n2);
        writeln(n3);
      end;
    close(SOSUB);
    readln;
  end;
end.

Mas aparece um outro problema. No arquivo SOSUB tem dois valores e ele tá lendo só o primeiro valor e apresentando error 103.

 

 

 

 

 

 

 

Link para o comentário
Compartilhar em outros sites

Olá @SuperBond, tudo bem?

 

 

SuperBond, teria como explicar em palavras mesmo o que você gostaria que o seu programa fizesse?

 

 

Por exemplo, se o arquivo SOSUB.txt tivesse o seguinte conteúdo:

 

12312354

3109812

7834628

74834079

 

ele imprimiria cada um desses números, digito a digito, em cada linha. Procede? Poderia fornecer um exemplo de como seria a saída do seu programa?

 

 

 

NW

Link para o comentário
Compartilhar em outros sites

Fala LNW! como vai?

Desculpe demorar pra retornar, tanta coisa pra fazer... é por isso que resumi demais os posts e faltou informações. Mas vamos lá. Eu tenho dois exercicios que nao estava conseguindo resolver. Um era pra ler uma string armazenad em um arquicvo de texto. Essa ja resolvemos usando to length.

O outro exercicio eu devo manipular dois arquivos de texto, SOSUB.text e OPERA.text. Na minha opinião é um exercicio meio pobre, mas nos foi passado assim. E o professor não é muito interessado (_( Bem, os numeros no SOSUB são, por ex.:

 

091

478

 

 

E no arquivo OPERA, por ex.:

 

123

357

 

Os nº do arquivo SOSUB devem somar com os do OPERA desse jeito:

 

0+1

9+2

1+3

 

0+3

9+5

1+7

 

4+1

7+2

8+3

 

4+3

7+5

8+7

 

 

E na tela só aparece o resultado de cada operação, escrito em linha:

0+1

9+2   resultado: 1114

1+3

 

0+3

9+5   resultado: 3148

1+7

 

4+1

7+2   resultado: 5911

8+3

 

4+3

7+5    resultado: 71215

8+7

 

O problema é que o resultado na tela é somente 1114, ou seja ele tá operando só com o 091 e o 123. Alem de apresnetar erro 103.

O código é esse:

 

 

 
program SOSUB;
var
  SOSUB, OPERA: Text;
  i, j, n1, n2, n3, o1, o2, o3, r1, r2, r3:integer;
  NUM:array[1..10] of integer;
  OP:array[1..10] of integer;
begin
assign(SOSUB, 'SOSUB.txt');
reset(SOSUB);
assign(OPERA, 'OPERA.txt');
reset(OPERA);
for i:=1 to 2 do
  for j:=1 to 2 do
    begin
      readln(SOSUB, NUM[i]);
      readln(OPERA, OP[j]);
      if (NUM[i]<100) then
        begin
          n1:=0;
          n2:=NUM[i] div 10;
          n3:=NUM[i]-(n2*10);
        end
          else
            begin
              n1:=NUM[i] div 100;
              n2:=(NUM[i]-(n1*100)) div 10;
              n3:=(NUM[i]-(n1*100)) - n2*10;
            end;
       if (OP[j]<100) then
         begin
           o1:=0;
           o2:=OP[j] div 10;
           o3:=OP[j]-(o2*10);
         end
           else
             begin
               o1:=OP[j]
               div 100;
               o2:=(OP[j]-(o1*100)) div 10;
               o3:=(OP[j]-(o1*100)) - o2*10;
               end;
       r1:=n1+o1;
       r2:=n2+o2;
       r3:=n3+o3;
       if (r1>=0) and (r1<=5) and (r2>=0) and (r2<=5) and (r3>=0) and (r3<=5) then
         writeln(r1,r2,r3);
       close(SOSUB);
       close(OPERA);
       readln;
     end;
end.

 

 
 

 

 

 

Link para o comentário
Compartilhar em outros sites

Olá @SuperBond

 

Só um pequeno comentário sobre o exercício ser pobre. Às vezes, o exercício apenas parece ser um pouco inocente, mas não é... e é o caso desse exercício. Não diria que é difícil, mas é do tipo que dá algum trabalho, principalmente se você for querer tratar consistências.

 

Agora entendi bem o que é pra ser feito e realmente não iria por essa via de querer tratar o número lido do arquivo como um valor inteiro. Ainda que o número tenha poucos dígitos.

 

Como você vai precisar somar cada dígito encontrado na string, uma boa dica seria fazer um pequeno cálculo valendo-se do valor ordinal do caractere (o dígito). Vou dar um exemplo:

str1:='12';str2:='34';d1 := Ord(str1[1]) - Ord('0') + Ord(str2[1]) - Ord('0');d2 := Ord(str1[2]) - Ord('0') + Ord(str2[2]) - Ord('0');

d1 e d2 são variáveis inteiras. d1 vai receber o valor 4, e d2, 6.

 

O cálculo é feito com base no valor ordinal (da ASCII) dos caracteres ('0'..'9').

 

Eu montei um exemplo com base no conteúdo dos arquivos:

 

SOSUB.txt

091
478

 

OPERA.txt

123
357
49723487234892
897432987429384
4879498734982789
478397982
0000000000
43434

 

 

Saída:

output.png

 

 

Vai ajudar bastante se você montar uma função exclusiva para a leitura da linha e que retorne True ou False de acordo com resultado dessa operação. Ou seja, foi possível ler a linha? Retorna True, caso contrário, retorne False. Para saber se já atingiu o fim de arquivo, teste com a função Eof().

 

 

Em linhas gerais, o seu algoritmo resume-se no seguinte:

 

 

1) Abra os dois arquivos;

 

2) Faça a leitura das linhas através de dois laços aninhados:

Enquanto (LerLinha(Arq1, String1)) FaçaInício   Enquanto (LerLinha(Arq2, String2)) Faça   Início      Somar e apresentar cada dígito de String1[i] e String2[i]   Fim   Reabra(Arq2)Fim

3) Feche os dois arquivos.

 

 

Observe que no meu exemplo acima, dígitos zero (à esquerda ou isolados) foram considerados na soma.. Eu acho que não deveria acontecer; 0000 é simplesmente 0. Ali, apenas faltou tratar essa questão do 0 à esquerda do número.

 

No seu exemplo, você considerou o dígito zero (à esquerda).

 

091 = 91

357

 

Deveria apresentar: 1267, e não 3148. Bom, é o que acho que seria mais natural. Inclusive, se esse número fosse lido como inteiro, ele seria guardado como 91.

 

 

Bom, não sei se deu para clarear as ideias... É a forma como vejo para resolver esse problema.

 

 

 

LNW

Link para o comentário
Compartilhar em outros sites

str1:='12';str2:='34';d1 := Ord(str1[1]) - Ord('0') + Ord(str2[1]) - Ord('0');d2 := Ord(str1[2]) - Ord('0') + Ord(str2[2]) - Ord('0');

LNW, entendi que str1 e str2 são constantes, como se fossem os números lidos dos arquivos, certo?

Pode me explicar o que acontece nos cálculos? 

Eu entendi que str1[1]) = 1 e str2[1]) = 3. Aí soma e resulta em 4.

Mas qual a função de Ord('0')?

Link para o comentário
Compartilhar em outros sites

@SuperBond

 

Essa função retorna o valor ordinal de um caractere passado como argumento. Dê uma olhada aqui: http://www.asciitable.com

 

O cálculo ali é feito com esses valores ordinais retornados para aqueles caracteres. Eu não tenho como calcular diretamente '1' + '3'. Se você olhar na tabela, vai ver que o '0' tem valor ASCII 48 e o '3' tem valor 51. Logo, para obter obter o dígito inteiro 3, eu faço: 51 - 48 = 3. Isso foi para evitar usar a função Val(). Se eu posso imprimir a soma dos dígitos diretamente:

Write(Ord(str1[1]) - Ord('0') + Ord(str2[1]) - Ord('0'));

[ ]'s

 

NW

Link para o comentário
Compartilhar em outros sites

Estou perto de resolver essa questão, já tive algum progresso. Usei suas sugestões. Mas o código ainda não faz todas as operações necessarias. No arquivos NUM e OPERA tem os seguintes numeros:

 

NUM.text

141032

OPERA.txt

211453

A saida está sendo somente: 352 e 485. Quer dizer, ele está fazendo:

 

1+2=3

4+1=5

1+1=2

 

e

 

0+4=4

3+5=8

2+3=5

 

 

Mas ainda faltam:

 

1+4=5

4+5=9

1+3=4

 

0+2=2

3+1=4

2+1=3

 

Já tentei bastante,mas só cheguei até esses dois resultados, 352 e 485. Deve estar faltando um laço de repetição em algum trecho, mas não sei como. O código:

program SOMAS;vari,j, r1, r2, r3:integer;d, f:string[10];NUM, OPERA: Text;//n, op:array[1..10] of string[10];beginassign(NUM, 'NUM.txt');  reset(NUM);assign(OPERA, 'OPERA.txt');  reset(OPERA);  i:=1;  j:=1;  while not eof(NUM) and not eof(OPERA) do  begin  readln(NUM, n[i]);  readln(OPERA, op[j]);  d:=n[i];  f:=op[j];  r1:=ord(d[1])-Ord('0')+ord(f[1])-Ord('0');  r2:=ord(d[2])-Ord('0')+ord(f[2])-Ord('0');  r3:=ord(d[3])-Ord('0')+ord(f[3])-Ord('0');  writeln(r1,r2, r3);  end;  close(NUM);  close(OPERA);readln;end.
Link para o comentário
Compartilhar em outros sites

@SuperBond

 

 

Já tentei bastante,mas só cheguei até esses dois resultados, 352 e 485. Deve estar faltando um laço de repetição em algum trecho, mas não sei como.

 

Sim, na verdade é preciso desmembrar aquela condição que você colocou no seu laço while em mais um laço independente. Você precisa percorrer ambos os arquivos, cada um com um laço de repetição. É o que demonstro no algoritmo que postei acima.

 

Você também não precisa ficar engessado com apenas três dígitos como está sendo feito. Vou postar um exemplo mais abaixo para exemplificar.

 

Seguindo o que você fez no seu programa, para corrigi-lo, basta aninhar os laços de repetição:

Program SOMAS;Uses CRT;Var   r1, r2, r3: integer;  d, f: string[10];  NUM, OPERA: Text;Begin  ClrScr;  assign(NUM, 'NUM.txt');  reset(NUM);  assign(OPERA, 'OPERA.txt');  reset(OPERA);  While Not eof(NUM) Do    Begin      readln(NUM, d);      While Not eof(OPERA) Do        Begin          readln(OPERA, f);          r1 := ord(d[1])-Ord('0') + ord(f[1])-Ord('0');          r2 := ord(d[2])-Ord('0') + ord(f[2])-Ord('0');          r3 := ord(d[3])-Ord('0') + ord(f[3])-Ord('0');          writeln(r1,r2, r3);        End;      Reset(OPERA);    End;  close(NUM);  close(OPERA);  readln;End.

Note o Reset ao final do laço mais externo que serve justamente para reabrir o arquivo OPERA.txt para que possa ser lido novamente desde o início.

 

 

Sobre a questão de não ficar preso a apenas 3 dígitos. Analise o seguinte exemplo:

Program SomaDig;Uses CRT;Var  s1, s2: String[60];  i     : Integer;Begin  ClrScr;  s1 := '47893498398749834';  s2 := '12323283621671587';  For i := 1 To Length(s1) Do    Begin      Write(Ord(s1[i])-Ord('0') + Ord(s2[i])-Ord('0'));    End;End.

s1 e s2 seriam justamente as linhas que você leria dos arquivos. Perceba que não foi necessário usar variáveis intermediárias para receber os dígitos. Basta mandar imprimir com Write. Neste exemplo, estou considerando strings com tamanho iguais. Se não tiverem tamanhos iguais, aí você vai precisar tratar essa questão também.

 

 

 

 

[ ]'s

 

LNW

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...