• Publicidad

Problema con la comparación de cadenas que contienen números

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

Problema con la comparación de cadenas que contienen números

Notapor thedj » 2009-05-04 12:21 @556

Muy buenas tardes, resulta que necesito mostrar la UID y nombre de usuario cuando me convenga a través de una condición de if(). Los valores antes del if() me los pilla bien, pero cada vez que la comprobación del if() es correcta, me salta el siguiente error:

Código: Seleccionar todo
Use of uninitialized value in concatenation (.) or string at usugrupo3.pl line 182, <ENTRADA> line 11.


Os dejo el cacho de código que da el problema a ver si me podéis echar un cable:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
            open(ENTRADA,$FICH_USU) or die "Error: no se puede abrir el fichero";
            $cont=0;
            $comprueba=numero(\$$grupo);
            if($comprueba){
                while($usuario = <ENTRADA>){
                    @usuario=split(/:/,$usuario);
                    print "usu3 vale $usuario[3] y grupo vale $$grupo\n"; #Muestra los datos correctamente
                    if($usuario[3] ==  $$grupo) #línea 179 error de abajo
                    {
                        $cont=1;
                        print "$nombre[0]    $nombre[2]    primario\n"; #línea 182 error de arriba
                    }
                }
                close(ENTRADA);
                open(ENTRADA,$FICH_GRU) or die "Error: no se puede abrir el fichero";
               
                while($usuario = <ENTRADA>){
                    @usuario=split(/:/,$usuario);
                    if($usuario[2] == $$grupo)#Porque puede haber algun grupo en el archivo etc/group, que no contenga ningún usuario
                    {
                        $cont=1;
                        $numuid=comprueba_uid($nombre[3]);
                        print "$nombre[3]    UID   secundario\n";
                    }
                }
                close(ENTRADA);
                if($cont == 0){
                    print "Error: el grupo $$grupo no existe\n";
                }
            }
 
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Decir, que antes de nada hago una comprobación para ver si es un número.

Otro error que sale, relacionado con lo anterior es:

Código: Seleccionar todo
Argument "" isn't numeric in numeric eq (==) at usugrupo3.pl line 179, <ENTRADA> line 15.
Última edición por thedj el 2009-05-04 12:49 @575, editado 1 vez en total
thedj
Perlero nuevo
Perlero nuevo
 
Mensajes: 15
Registrado: 2009-05-03 17:15 @760

Publicidad

Notapor explorer » 2009-05-04 13:05 @587

El primer mensaje de error dice que en el print() estás usando una variable que tiene un valor indefinido (undef). Eso quiere decir que $nombre[0] y/o $nombre[2] no tienen ningún valor. De hecho, no sabemos dónde y cómo se inicializa el arreglo @nombre. ¿No será @usuario el que quieres utilizar?

El segundo error dice que has intentado comparar numéricamente la cadena vacía con otro valor. Es solo una alerta. Para dejar que te moleste, antes de la comparación, haz: $usuario[3] = 0+$usuario[3];.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor thedj » 2009-05-04 13:25 @601

Muy buenas de nuevo, el error que comentabas de @usuario tenías razón, era tal y como has dicho, pero en un código de más de 300 líneas ya me estaba volviendo loco para localizar el error. jejeje, supongo que la experiencia hará que lo vaya viendo más claro.

Por otra parte el otro error, no lo tengo tan claro, lo que pretendo es comparar la GID que se ha introducido por teclado, con la GID del grupo de cada usuario. Y entra en el if(), tal y como me has corregido, entonces no entiendo el error.

La zona conflictiva quedaría así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
 if($usuario[3] ==  $$grupo) #Argument "" isn't numeric in numeric eq (==) at usugrupo3.pl line 179, <ENTRADA> line 15.

                    {
                        $cont=1;
                        print "$usuario[0]    $usuario[2]    primario\n";
                    }
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


PD: El print() lo hace el número de veces correcto y se realiza bien.

Un saludo.
thedj
Perlero nuevo
Perlero nuevo
 
Mensajes: 15
Registrado: 2009-05-03 17:15 @760

Notapor explorer » 2009-05-04 13:35 @607

Para descubrir el primer tipo de errores, pon
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
use strict;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

al principio del programa.

Para el segundo caso. Se trata de una operación de comparación numérica, y como una de las variables (yo creo que $usuario[3]) es "" (cadena vacía), Perl te avisa (porque estará activado el sistema de alertas -w o use warnings;) de que no puede hacer de forma directa esa comparación ya que la cadena vacía no es un número. Perl, de todas maneras, sí que hará bien la comparación porque al final intentará pasarlo a número. Para evitar el aviso, haz lo que te dije. O cambia el if() por

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
if ($usuario[3] and $usuario[3] ==  $$grupo) {
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


que de esa manera primero comprobamos que no es una cadena vacía.

El print() lo hace bien porque se trata de una de cadena de caracteres, tanto si es un número GID o la cadena vacía.

Recuerda que en el fichero passwd o groups, algunos de los campos pueden estar vacíos.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor thedj » 2009-05-07 13:45 @614

Muy buenas tardes de nuevo.

En muchas líneas de mi código, me ha saltado el siguiente error:
Código: Seleccionar todo
Argument "" isn't numeric in numeric tal tal...

que según he podido entender es porque estoy intentando utilizar operadores de números ( == > ...) con cadena de caracteres. Este error en todos los casos los he resuelto de la forma que me comentaste en el mensaje anterior:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
if ($usuario[3] and $usuario[3] ==  $$grupo)
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
por ejemplo.

Mi problema es que este programa tengo que entregarlo y defenderlo ante el profesor, y necesitaría saber qué es lo que hace exactamente ese "and". O si hay alguna otra manera de pasar por ejemplo la cadena 64 a una variable que contenga dicho número pero como dato numérico.

Un cordial saludo, y gracias por su intención.
thedj
Perlero nuevo
Perlero nuevo
 
Mensajes: 15
Registrado: 2009-05-03 17:15 @760

Notapor explorer » 2009-05-07 14:42 @654

La línea
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
if ($usuario[3] and $usuario[3] ==  $$grupo)
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

es equivalente a
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
if ((defined($usuario[3]) and $usuario[3] ne '') and $usuario[3] ==  $$grupo)
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Es decir:
Comprobamos si $usuario[3] contiene un valor definido (que es lo mismo que decir que no contiene un valor undef)

y ('and')

Comprobamos que $usuario[3] es distinto de cadena vacía

y ('and')

$usuario[3] es igual, numéricamente a lo que contiene $$grupo.

Las condiciones se comprueban de izquierda a derecha. Y como todas son 'y', la primera que falle hará que salga del if() y no se comprueben el resto de condiciones.

Es claro que es más cómodo poner solo $usuario[3] en lugar de una condición más.

¿Por qué hacemos esa primera condición? Pues para asegurarnos que $usuario[3] contiene al menos "algo" con lo que podamos comparar con $$grupo.

El error te salía porque, en ocasiones, el split() te devolvía un undef. Y Perl te avisaba de que estaba haciendo una comparación numérica con un valor indefinido.

Para evitarlo está la opción anterior, en el if() o podemos aseguramos que, realmente, contiene un valor numérico:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$usuario[3] += 0;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Con esta sencilla suma, si el valor era indefinido, lo pasamos a 0, y ya podemos seguir con la comparación. Si ya fuera un número, no pasaría nada por sumarle 0.

Ahora ya puedes defenderlo frente al profesor... aunque... como tu profesor también está leyendo esto, quizás se le pueden ocurrir más preguntas :twisted:

¡A estudiar y practicar!

¡Suerte! (si estudias no la necesitarás)
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor thedj » 2009-05-07 15:05 @670

Pues mucha suerte sí que me hace falta, jejeje. Muchas gracias por la ayuda.
thedj
Perlero nuevo
Perlero nuevo
 
Mensajes: 15
Registrado: 2009-05-03 17:15 @760


Volver a Básico

¿Quién está conectado?

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