Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 31-01-2007
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.557
Poder: 25
egostar Va camino a la fama
Contar letras en un TMemo

Hola amigos,

Tengo un pequeño problema al contar las letras dentro de un memo.

Tengo dos alternativas, una simple y otra menos ortodoxa.

Código Delphi [-]
// Aqui la simple
procedure TForm1.Memo1Change(Sender: TObject);
begin
  StaticText1.Caption := inttostr(Length(Memo1.Lines.Text));
end;

Código Delphi [-]
//Aqui la no muy Ortodoxa
procedure TForm1.Memo1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  Case Key of
     8,46  : begin
          If Letras > 0 then begin
             Letras := Letras-1;
             StaticText1.Caption := inttostr(Letras);
          end;
     end;
     else begin
          case Key of
             13,16,20,35,36,37,38,39,40 : begin
             end;
             else begin
                    Letras := Letras+1;
                    StaticText1.Caption := inttostr(Letras);
             end;
          end;
     end;
  end;
end;

Mi problema existencial es que no quiero que cuente los enter en el memo solo las letras, numeros y espacios.

En la primera opcion que es la simple me cuenta los enter para sumar o para restar

En la segunda opcion no me suma los enter pero si los resta.

¿Hay algo que pueda hacer para que no me cuente los Enter?

Gracias anticipadas.
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #2  
Antiguo 31-01-2007
Avatar de Caral
[Caral] Caral is offline
Miembro Premium
 
Registrado: ago 2006
Posts: 7.659
Poder: 25
Caral Va por buen camino
Hola egostar
No se a que te refieres con los enter, supongo que a los espacios vacios entre las letras.
No se pero se me ocurre que si es text, por que no definir un:
Código Delphi [-]
If X = ' ' then
//otra cosa
Osea que si el espacio esta vacio no lo lea.
No se se me ocurre.
Saludos
Responder Con Cita
  #3  
Antiguo 31-01-2007
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.557
Poder: 25
egostar Va camino a la fama
Hola Caral, gracias por tu interes.

Me refiero a los ENTER que son los saltos de linea, no a los espacios entre palabras, esos si los estoy contando.

Saludos.
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #4  
Antiguo 31-01-2007
Avatar de Bicho
[Bicho] Bicho is offline
Miembro Premium
 
Registrado: jul 2003
Ubicación: Inca - Mallorca
Posts: 1.776
Poder: 22
Bicho Va por buen camino
Hola, quizá una función como esta te sirva:

Código Delphi [-]
 function Palabras(Cadena:string):integer;
 var
    n:integer;
    AntEspacio:boolean;
 begin
   AntEspacio:=FALSE;
   If Cadena='' then Result:=0 else Result:=1;
   for n:=1 to Length(Cadena) do
   begin
     if AntEspacio and
        (Cadena[n]<>' ')and
        (Cadena[n]<>#13)and
        (Cadena[n]<>#10)
                   then Inc(Result);

     AntEspacio:=(Cadena[n]=' ') or
                 (Cadena[n]=#13) or
                 (Cadena[n]=#10);
   end;
 end;

Saludos
Responder Con Cita
  #5  
Antiguo 31-01-2007
Avatar de ArdiIIa
[ArdiIIa] ArdiIIa is offline
Miembro Premium
 
Registrado: nov 2003
Ubicación: Valencia city
Posts: 1.481
Poder: 22
ArdiIIa Va por buen camino
Veamos


Código Delphi [-]
procedure TForm1.ContarLetras(Sender: TObject);
Var
I,Z: Integer;
cTemp :  String;
begin
Z := 0;
cTemp := Memo1.Lines.Text;
For I := 1 To  Length(cTemp) DO
if ord(cTemp[i]) < 32 then
inc(Z);

ShowMessage( IntToStr( Length(cTemp) - Z ));

end;
__________________
Un poco de tu generosidad puede salvar la vida a un niño. ASÍ DE SENCILLO
Responder Con Cita
  #6  
Antiguo 31-01-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Volviendo al método numero uno, el ortodoxo

Supongo que esto funcionaría:
Código Delphi [-]
procedure TForm1.Memo1Change(Sender: TObject);
var
  Str: String;
  i,j: integer;
begin
  Str:= Memo1.Lines.Text;
  j:= 0;
  for i:= 1 to Length(Str) do
    if (Str[i] <> #13) and (Str[i] <> #10) then
      inc(j);
  StaticText1.Caption:= IntToStr(j);
end;

Aunque supongo que ya habrías pensado en una solución parecida, entonces me pregunto si lo que te preocupaba es el tiempo que se tarda en contar los caracteres. Si es así lo podemos afinar un poco mas:
Código Delphi [-]
function Longitud(Str: PChar): Integer;
asm
        MOV     Result,0
        DEC     EAX
@@SIG:
        INC     EAX
        CMP     BYTE PTR [EAX],0
        JE      @@SALIR
        CMP     BYTE PTR [EAX],13
        JE      @@SIG
        CMP     BYTE PTR [EAX],10
        JE      @@SIG
        INC     Result
        JMP     @@SIG
@@SALIR:
end;

procedure TForm1.Memo1Change(Sender: TObject);
begin
  StaticText1.Caption:= IntToStr(Longitud(PChar(Memo1.Lines.Text)));
end;

En cuanto al segundo método, es complicado, piensa que cuando usas Enter se introducen dos caracteres y no uno, que puedes seleccionar y borrar mas de un carácter a la vez y ya no hablamos si utilizas el portapapeles ...
Responder Con Cita
  #7  
Antiguo 31-01-2007
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.557
Poder: 25
egostar Va camino a la fama
Muchas gracias ArdiIIa

Quedo de 10

Aqui pongo como quedó el código completo espero que sirva para futuras consultas.

Código Delphi [-]
unit UContadorLetras;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Buttons;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    StaticText1: TStaticText;
    Label1: TLabel;
    BitBtn1: TBitBtn;
    procedure FormShow(Sender: TObject);
    procedure Memo1Change(Sender: TObject);
    procedure ContarLetras;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Letras: Integer;

implementation

{$R *.DFM}

procedure TForm1.ContarLetras;
Var
  I,Z: Integer;
  cTemp :  String;
begin
  Z := 0;
  cTemp := Memo1.Lines.Text;
  For I := 1 to  Length(cTemp) do
      if ord(cTemp[i]) < 32 then
         inc(Z);
  StaticText1.Caption := IntToStr(Length(cTemp) - Z);
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  Letras := 0;
  StaticText1.Caption := inttostr(Letras);
end;

procedure TForm1.Memo1Change(Sender: TObject);
begin
  ContarLetras;
end;

end.

Saludos y nuevamente gracias.
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #8  
Antiguo 31-01-2007
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.557
Poder: 25
egostar Va camino a la fama
Vaya

Tambien este funcionó a la perfeccion.

Código Delphi [-]
unit UContadorLetras;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Buttons;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    StaticText1: TStaticText;
    Label1: TLabel;
    BitBtn1: TBitBtn;
    procedure FormShow(Sender: TObject);
    procedure Memo1Change(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Letras: Integer;

implementation

{$R *.DFM}

procedure TForm1.FormShow(Sender: TObject);
begin
  Letras := 0;
  StaticText1.Caption := inttostr(Letras);
end;

procedure TForm1.Memo1Change(Sender: TObject);
var
  Str: String;
  i,j: integer;
begin
  Str:= Memo1.Lines.Text;
  j:= 0;
  for i:= 1 to Length(Str) do
    if (Str[i] <> #13) and (Str[i] <> #10) then
      inc(j);
  StaticText1.Caption:= IntToStr(j);
end;

end.

Muchas gracias seoane.
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #9  
Antiguo 31-01-2007
Avatar de Caral
[Caral] Caral is offline
Miembro Premium
 
Registrado: ago 2006
Posts: 7.659
Poder: 25
Caral Va por buen camino
Hola, Bueno, los dos funcionan muy bien y hacen casi lo mismo, pero:
Me he quedado con que cuentan tambien los espacios en blanco, como hacer para que no los cuente.
Osea contar letras, pues que cuente letras, no espacios entre ellas, al igual que no cuenta el enter o salto de renglon.
Saludos
Responder Con Cita
  #10  
Antiguo 31-01-2007
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.557
Poder: 25
egostar Va camino a la fama
Perdon Bicho pero no vi tu post antes de contestar a los demas, gracias por el aporte.

Saludos.
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #11  
Antiguo 31-01-2007
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.557
Poder: 25
egostar Va camino a la fama
Cita:
Empezado por seoane
Aunque supongo que ya habrías pensado en una solución parecida, entonces me pregunto si lo que te preocupaba es el tiempo que se tarda en contar los caracteres. Si es así lo podemos afinar un poco mas:
Realmente no me preocupa el tiempo en el conteo, incluso es imperceptible, de todos modos estoy analizando tu código ASM que me parece muy interesante aunque un poco fuera de mi alcance en este momento.

Saludos.
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #12  
Antiguo 31-01-2007
Avatar de ArdiIIa
[ArdiIIa] ArdiIIa is offline
Miembro Premium
 
Registrado: nov 2003
Ubicación: Valencia city
Posts: 1.481
Poder: 22
ArdiIIa Va por buen camino
Cita:
Empezado por Caral
Hola, Bueno, los dos funcionan muy bien y hacen casi lo mismo, pero:
Me he quedado con que cuentan tambien los espacios en blanco, como hacer para que no los cuente.
Osea contar letras, pues que cuente letras, no espacios entre ellas, al igual que no cuenta el enter o salto de renglon.
Saludos
Código Delphi [-]
procedure TForm1.ContarLetras;
Var
  I,Z: Integer;
  cTemp :  String;
begin
  Z := 0;
  cTemp := Memo1.Lines.Text;
  For I := 1 to  Length(cTemp) do
      if ord(cTemp[i]) < 33 then
         inc(Z);
  StaticText1.Caption := IntToStr(Length(cTemp) - Z);
end;
__________________
Un poco de tu generosidad puede salvar la vida a un niño. ASÍ DE SENCILLO
Responder Con Cita
  #13  
Antiguo 31-01-2007
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.557
Poder: 25
egostar Va camino a la fama
Cita:
Empezado por Caral
Hola, Bueno, los dos funcionan muy bien y hacen casi lo mismo, pero:
Me he quedado con que cuentan tambien los espacios en blanco, como hacer para que no los cuente.
Osea contar letras, pues que cuente letras, no espacios entre ellas, al igual que no cuenta el enter o salto de renglon.
Saludos
Usando el mismo procedimiento de seoane, aqui esta para no contar espacios tampoco

Código Delphi [-]
procedure TForm1.Memo1Change(Sender: TObject);
var
  Str: String;
  i,j: integer;
begin
  Str:= Memo1.Lines.Text;
  j:= 0;
  for i:= 1 to Length(Str) do
    if (Str[i] <> #13) and (Str[i] <> #10) and (Str[i] <> #32) then
      inc(j);
  StaticText1.Caption:= IntToStr(j);
end;

Saludos
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #14  
Antiguo 31-01-2007
Avatar de Caral
[Caral] Caral is offline
Miembro Premium
 
Registrado: ago 2006
Posts: 7.659
Poder: 25
Caral Va por buen camino
Hola ArdiIIa
Perdona, pero lo haces facil.
Como buen aprendiz, no me quedo solo con el cambio de 32 x 33
Por que?
a que se debe?
tiene relacion con la cantidad de letras del abecedario?
El #13 es enter
El #33 es Espacio?
Me lo explicas, por favor.
Saludos
Responder Con Cita
  #15  
Antiguo 31-01-2007
Avatar de Caral
[Caral] Caral is offline
Miembro Premium
 
Registrado: ago 2006
Posts: 7.659
Poder: 25
Caral Va por buen camino
Interesante, las dos opiones.
Varian en muy poco, pero tienen el mismo efecto.
No se para que me pueda servir el codigo, pero una cosa si tengo clara.
Aqui se aprende muchisimo y eso que no hice yo la pregunta.
Saludos Maestros
Responder Con Cita
  #16  
Antiguo 31-01-2007
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.557
Poder: 25
egostar Va camino a la fama
Cita:
Empezado por Caral
Interesante, las dos opiones.
Varian en muy poco, pero tienen el mismo efecto.
No se para que me pueda servir el codigo, pero una cosa si tengo clara.
Aqui se aprende muchisimo y eso que no hice yo la pregunta.
Saludos Maestros
Pues mira, te comento para que se va a usar, tengo un cliente que escribe articulos para una revista, resulta que la editora le pide que sean de una cantidad de caracteres máxima, entonces con ese código no tiene que estar contando letra por letra cuantas lleva, una vez que termine con un botón lo quiere mandar por correo, pero eso ya es otra historia que solucionaré con Indy.

Bueno a grandes rasgos para eso lo requeria.

Saludos y gracias por el interes y sobre todo por la rapidez de sus respuestas.
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #17  
Antiguo 31-01-2007
Avatar de Caral
[Caral] Caral is offline
Miembro Premium
 
Registrado: ago 2006
Posts: 7.659
Poder: 25
Caral Va por buen camino
Hola
Me imagine que por ai podia andar, pero pense en una aplicacion de tipo didactica, para estudiantes, creia que podia ser para algo asi.
Pero no deja de ser muy interesantes las posivilidades del codigo de estos maestros.
Saludos
Responder Con Cita
  #18  
Antiguo 31-01-2007
Avatar de ArdiIIa
[ArdiIIa] ArdiIIa is offline
Miembro Premium
 
Registrado: nov 2003
Ubicación: Valencia city
Posts: 1.481
Poder: 22
ArdiIIa Va por buen camino
Cita:
Empezado por Caral
Hola ArdiIIa
Perdona, pero lo haces facil.
Como buen aprendiz, no me quedo solo con el cambio de 32 x 33
Por que?
a que se debe?
tiene relacion con la cantidad de letras del abecedario?
El #13 es enter
El #33 es Espacio?
Me lo explicas, por favor.
Saludos
Está claro, es el código ASCII de cada letra, ESPACIO = 32
luego si le dices que incremente Z cada vez que el caracter sea inferior a 32, el resultado es lo que se esperaba, todos los caracteres por debajo de 32, son caracteres de control, no letras. así de sencillo.
__________________
Un poco de tu generosidad puede salvar la vida a un niño. ASÍ DE SENCILLO
Responder Con Cita
  #19  
Antiguo 01-02-2007
Avatar de Caral
[Caral] Caral is offline
Miembro Premium
 
Registrado: ago 2006
Posts: 7.659
Poder: 25
Caral Va por buen camino
Muchas Gracias por tu explicacion ArdiIIa
Me queda claro.
Saludos
Responder Con Cita
  #20  
Antiguo 01-02-2007
Avatar de ArdiIIa
[ArdiIIa] ArdiIIa is offline
Miembro Premium
 
Registrado: nov 2003
Ubicación: Valencia city
Posts: 1.481
Poder: 22
ArdiIIa Va por buen camino
Por abundar un poquito mas y examinando el ASM de seoane aún se puede optimizar algo mas quitando unas líneas y cambiando otras, seguramente ganemos en rapidez...

Código Delphi [-]
function Longitud(Str: PChar): Integer;
asm
        MOV     Result,0
        DEC     EAX
@@SIG:
        INC     EAX
        CMP     BYTE PTR [EAX],0
        JE      @@SALIR
        CMP     BYTE PTR [EAX],33
        JB      @@SIG
        INC     Result
        JMP     @@SIG
@@SALIR:
end;
__________________
Un poco de tu generosidad puede salvar la vida a un niño. ASÍ DE SENCILLO
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Contar Dtos en un SQl IVAND SQL 7 03-08-2006 23:25:35
contar caracteres Cosgaya Varios 1 04-06-2005 17:40:54
Contar Dias Paradiso Varios 2 27-06-2004 11:35:30
Contar Caracteres Nuria Varios 2 29-12-2003 10:36:46
Problema con contar kao SQL 3 07-07-2003 10:47:14


La franja horaria es GMT +2. Ahora son las 21:26:06.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi