Página 1 de 1

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

NotaPublicado: 2009-05-04 12:21 @556
por thedj
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.

NotaPublicado: 2009-05-04 13:05 @587
por explorer
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];.

NotaPublicado: 2009-05-04 13:25 @601
por thedj
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.

NotaPublicado: 2009-05-04 13:35 @607
por explorer
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.

NotaPublicado: 2009-05-07 13:45 @614
por thedj
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.

NotaPublicado: 2009-05-07 14:42 @654
por explorer
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)

NotaPublicado: 2009-05-07 15:05 @670
por thedj
Pues mucha suerte sí que me hace falta, jejeje. Muchas gracias por la ayuda.