• Publicidad

Problemas con código

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Problemas con código

Notapor eandres25 » 2010-07-16 18:29 @811

Hola a todos, espero que esto esté bien posteado aquí, tengo un problema con el siguiente código, espero me ayuden.

No sé qué tiene mal mi código, pero hay algo fuera de lo normal. Sé que no es el mejor código del mundo y yo soy muy principiante en esto. Les pego el código:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $scripts_dir = "/usr/local/bin/doc11";
  2. open (ARCHIVO, "$scripts_dir/Equipos.txt");
  3.  
  4. $cant_equipos = 0;
  5.          
  6. @equipos=0;
  7.  
  8. while(<ARCHIVO>)
  9. {
  10.         chomp;
  11.         my @line = split(/\t/);
  12.  
  13.         $num_args = 0;
  14.         while ($num_args <= 1){
  15.                 $equipos[$cant_equipos][$num_args] = $line[$num_args];
  16.                 $num_args++;
  17.         }
  18.         $cant_equipos++;
  19. }
  20. close(ARCHIVO);
  21.  
  22. do {
  23.        
  24.         print "\nEscriba el numero del equipo que desea accesar:\n\n";
  25.        
  26.         for ($m = 0; $m < $cant_equipos; $m++){
  27.                 print "\t$m. $equipos[$m][0]\n";
  28.         }
  29.  
  30.         print "\nDigite su eleccion y presione enter: ";
  31.         $num_router=<STDIN>;
  32.         chop($num_router);
  33.        
  34. }
  35. while ($num_router < 0 || $num_router >= $cant_equipos);
  36.  
  37.  
  38. if($num_router == 0){
  39. die "Hasta Pronto\n";
  40. }
  41.  
  42. else {
  43.         $router = $equipos[$num_router][1];
  44.         print "El router es: $router";
  45.         print " antes era: $equipos[$num_router][1] \n";
  46.         }
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4



En la línea 45, estoy imprimiendo lo mismo, pero es a modo de prueba, pues al ejecutar el código me tira lo siguiente:

Escriba el numero del equipo que desea accesar:

0. Salir
1. Equipo1
2. Equipo2
3. Equipo3
4. Equipo4

Digite su eleccion y presione enter: 1

antes era: 172.16.1.1


Como ven, no está imprimiendo la primera vez, lo cual me parece raro y además no realiza las acciones que debe realizar más adelante, cosa que sí realiza bien con la otra versión del programa que tengo (ahora quiero poner los equipos en un archivo aparte para mayor flexibilidad y no cambiar el código al agregar equipos nuevos). El archivo contiene lo siguiente:

Salir 0
Equipo1 172.16.1.1
Equipo2 172.16.1.2
Equipo3 172.16.1.3
Equipo4 172.16.1.4


Los espacios en realidad son tabuladores.

Si realizo la impresión de manera distinta muestra otra cosa. Ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     else {
  2.         $router = $equipos[$num_router][1];
  3.         print "El router es: $router\nfafafa\n";
  4.         print " antes era: $equipos[$num_router][1] \n";
  5. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4



El resultado es:

Escriba el numero del equipo que desea accesar:

0. Salir
1. Equipo1
2. Equipo2
3. Equipo3
4. Equipo4

Digite su eleccion y presione enter: 1
El router es: 172.16.1.1
fafafa
antes era: 172.16.1.1


Como ven, esto se aproxima un poco más a lo que quiero, pero no sé por qué no está interpretando bien.
Algo interesante es que absolutamente todo funciona muy bien al elegir la última opción, no sé si me estaré pasando algo por alto.

Digite su eleccion y presione enter: 4
El router es: 172.16.1.4 antes era: 172.16.1.4
Conectando al router...

Espere un momento...


ACTUALIZACION: Otra prueba, al agregar un retorno de carro al último equipo en el archivo externo me doy cuenta de que ya falla el programa y además me imprime el último octeto de la IP nuevamente:

Digite su eleccion y presione enter: 1
antes era: 172.16.1.4.4


Si en el archivo pongo 172.16.1.44 imprime 172.16.1.44.44

Espero haber sido claro. ¡Les agradezco mucho!

P.D.: Mi versión de Perl es: v5.8.4 built for i386-linux-thread-multi
eandres25
Perlero nuevo
Perlero nuevo
 
Mensajes: 13
Registrado: 2010-06-15 19:00 @833

Publicidad

Re: Problemas con código

Notapor explorer » 2010-07-17 06:05 @295

Esto me suena a que hay algún retorno de carro al final del segundo campo de la línea, y eso hace que no lo veamos, ya que queda sobreescrito con el siguiente print().

Una forma de asegurarse de qué es lo que se está imprimiendo, es lo que has hecho: un print() por cada salida. Y además, poniéndolo entre corchetes, para ver hasta dónde llega cada una de ellas. Así no verás salidas mezcladas.

Por ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. #use 5.010;
  3. #use strict;
  4. #use warnings;
  5. #use diagnostics;
  6.  
  7. #use autodie;
  8.  
  9. my $scripts_dir = "/usr/local/bin/doc11";
  10.  
  11. ## Lectura
  12. my @equipos;
  13. open my $ARCHIVO, q[<], "$scripts_dir/Equipos.txt";
  14. while (<$ARCHIVO>) {
  15.         chomp;
  16.  
  17.         push @equipos, [ split /\t/ ];
  18. }
  19. close   $ARCHIVO;
  20.  
  21. ## Menú
  22. my $num_router;
  23.  
  24. do {
  25.     do {
  26.         print "\nEscriba el número del equipo que desea acceder:\n\n";
  27.  
  28.         for my $i ( 0 .. $#equipos ) {
  29.             print "\t$i\t$equipos[$i][0]\n";
  30.         }
  31.  
  32.         print "\nDigite su elección y presione enter: ";
  33.         chomp($num_router = <STDIN>);
  34.  
  35.     } while ($num_router eq ''  or  $num_router < 0  or  $num_router >= @equipos);
  36.  
  37.     if ($num_router) {
  38.         my $router = $equipos[$num_router][1];
  39.         print "El router es: [$router] Antes era: [$equipos[$num_router][1]]\n";
  40.     }
  41. } while ($num_router);
  42.  
  43. print "Hasta pronto\n";
  44.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Problemas con código

Notapor eandres25 » 2010-07-19 17:47 @783

Mmm, me sale esto (con el código exactamente como lo pusiste):
] Antes era:[172.16.1.44


Es más, copié exactamente el mismo código en un archivo nuevo, sin todo lo que viene debajo y es ese resultado.

¡Gracias!
eandres25
Perlero nuevo
Perlero nuevo
 
Mensajes: 13
Registrado: 2010-06-15 19:00 @833

Re: Problemas con código

Notapor explorer » 2010-07-20 03:05 @170

Entonces está claro... las líneas del fichero Equipos.txt tienen un carácter de retorno de carro, que es lo que hace el efecto de colocar el cursor al principio de la línea.

Si en el código hay un chomp(), entonces resulta que está eliminando un final de línea que no corresponde con el mismo final de línea del fichero.

Si, por ejemplo, edito el fichero Equipos.txt y le pongo finales de línea al estilo MSDOS:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
explorer@joaquin:~/Documents/Desarrollo> hexdump -C kk.txt
00000000  53 61 6c 69 72 09 30 0d  0a 45 71 75 69 70 6f 31  |Salir.0..Equipo1|
00000010  09 31 37 32 2e 31 36 2e  31 2e 31 0d 0a 45 71 75  |.172.16.1.1..Equ|
00000020  69 70 6f 32 09 31 37 32  2e 31 36 2e 31 2e 32 0d  |ipo2.172.16.1.2.|
00000030  0a 45 71 75 69 70 6f 33  09 31 37 32 2e 31 36 2e  |.Equipo3.172.16.|
00000040  31 2e 33 0d 0a 45 71 75  69 70 6f 34 09 31 37 32  |1.3..Equipo4.172|
00000050  2e 31 36 2e 31 2e 34 0d  0a                       |.16.1.4..|
00000059
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
ves que los finales de línea son del tipo 0x0D, 0x0A (retorno de carro, avanza de línea).
Si este fichero se lo paso al programa, me sale la misma salida que a ti:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Digite su elección y presione enter: 1
] Antes era: [172.16.1.11
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

debido a que el chomp() ha eliminado solo los caracteres de avance de línea, ya que yo estoy ejecutando el programa en un ordenador con sistema operativo Linux, donde por defecto, los finales de línea se definen solo con el carácter avance de línea. Los caracteres de retorno de carro siguen estando ahí.

Lo que tenemos que hacer es quitar ese carácter de retorno de carro.

Hay varias soluciones...

1.- Podemos modificar la apertura del fichero para indicar cómo es ese fichero:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open my $ARCHIVO, q[<:crlf], "kk.txt";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Ahora Perl sabe que se trata de un fichero con líneas terminadas en crlf. El problema ahora es... ¿estamos seguros de que el fichero Equipos.txt SIEMPRE va a tener esos finales de línea?

2.- Modificamos el indicador de cómo son los finales de línea:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. { local $/="\r\n";
  2. # sigue lo mismo que antes: open(), while(), close()...
  3. } # línea 21
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Aquí es necesario que modifiquemos el valor de $/ de forma local. Por eso hay que meter toda la operación entre llaves, para que no afecte luego a la operación de lectura del menú. Lo malo de esta operación es que tiene el mismo problema que el anterior.

3.- Quitar explícitamente el carácter que sobra:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.         chop;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
También tenemos el mismo problema de antes.

4.- Quitar los caracteres finales mediante una expresión regular. Cambiamos la línea 15 por
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.         s/[\r\n]//g;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Así, no nos importará cuáles sean los caracteres de final de línea que traigan las líneas de Equipos.txt, pues serán eliminados.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Problemas con código

Notapor eandres25 » 2010-07-20 09:53 @453

Claro, ese fue el problema: también ejecuto el código en Linux, pero como en mi empresa se usa Windows entonces creé el documento de texto con Notepad++ en Windows y lo copié por sftp. Lo que hice ahora fue editar el archivo en Linux y el problema se solucionó. Es increíble los problemas que da el trabajar con Windows. Y claro, mi falta de experiencia en esto.

¡Muchas gracias nuevamente, Explorer!
eandres25
Perlero nuevo
Perlero nuevo
 
Mensajes: 13
Registrado: 2010-06-15 19:00 @833


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 2 invitados

cron