2011-03-08 34 views
5

Escribo un programa simple en Matlab y me pregunto cuál es la mejor manera de garantizar que el valor que ingresa un usuario es un entero adecuado.La mejor manera de obligar a un usuario a ingresar un número entero en Matlab

Actualmente estoy usando esto:

while((num_dice < 1) || isempty(num_dice)) 
    num_dice = input('Enter the number of dice to roll: '); 
end 

Sin embargo lo que realmente sé que debe haber una mejor manera, porque esto no funciona todo el tiempo. También me gustaría agregar la comprobación de errores a un bloque try catch. Soy nuevo para Matlab, así que cualquier comentario sobre esto sería genial.

Edit2:

try 
    while(~isinteger(num_dice) || (num_dice < 1)) 
     num_dice = sscanf(input('Enter the number of dice to roll: ', 's'), '%d'); 
    end 

    while(~isinteger(faces) || (faces < 1)) 
     faces = sscanf(input('Enter the number of faces each die has: ', 's'), '%d'); 
    end 

    while(~isinteger(rolls) || (rolls < 1)) 
     rolls = sscanf(input('Enter the number of trials: ', 's'), '%d'); 
    end 
catch 
    disp('Invalid number!') 
end 

Esto parece estar funcionando. ¿Hay algo notablemente incorrecto con esto? EsEntero se define por la respuesta aceptada

+0

La parte 'catch' de tu bloque try-catch nunca será ingresada. Si la prueba 'while' falla, el ciclo simplemente se detiene, es decirno se encuentra ningún error para activar el 'catch'. –

+0

Las excepciones fueron posibles desde la función de entrada. Si ingresas algo como '<' o '-' y tratas de ponerlo en una variable, obtienes un colapso. Lo he arreglado ahora usando sscanf – Tanner

+0

. Puede que le interese la función [ROLL] (http://www.mathworks.com/matlabcentral/fileexchange/27327-a-dice-roller-for-matlab), que es un rodillo de dados para Matlab. – Jonas

Respuesta

7

La siguiente puede ser utilizado directamente en el código y cheques contra entrada no entero incluyendo valores vacíos, infinitos e imaginaria:

isInteger = ~isempty(num_dice) ... 
      && isnumeric(num_dice) ... 
      && isreal(num_dice) ... 
      && isfinite(num_dice) ... 
      && (num_dice == fix(num_dice)); 

Lo anterior sólo funcionará correctamente para escalar entrada. Para probar si una matriz multidimensional contiene sólo números enteros que puede utilizar:

isInteger = ~isempty(x) ... 
      && isnumeric(x) ... 
      && isreal(x) ... 
      && all(isfinite(x)) ... 
      && all(x == fix(x)) 

EDITAR

Estos prueba para cualquier valor entero . Para restringir los valores válidos a números enteros positivos, agregue un num_dice > 0 como en @MajorApus's answer.

Puede utilizar lo anterior para forzar al usuario que introduzca un número entero haciendo un bucle hasta que sucumben a sus demandas:

while ~(~isempty(num_dice) ... 
      && isnumeric(num_dice) ... 
      && isreal(num_dice) ... 
      && isfinite(num_dice) ... 
      && (num_dice == fix(num_dice)) ... 
      && (num_dice > 0)) 
    num_dice = input('Enter the number of dice to roll: '); 
end 
+0

Sí, ya hice una función usando la tuya junto con la parte> 0 añadida. Ahora me pregunto cómo debería estar protegiéndome contra la entrada no válida en la línea de entrada. ¿Cuál es la mejor manera de volver a solicitar información cuando se lanza una excepción? – Tanner

+0

@Tanner: Agregué un uso de ejemplo a mi respuesta que vuelve a solicitar la entrada cuando el usuario ingresa una entrada no válida. –

+0

Muchas gracias. Agregué un código más a mi pregunta original, ¿hay algo de malo en hacerlo de esa manera? Algo sobre matlab me está matando. C, C++, C#, Java, VB cualquiera de los que hubiera hecho esto hace una hora pero no matlab! – Tanner

0

Tome la entrada como una cadena y usar sscanf (http: //www.mathworks .com/help/techdoc/ref/sscanf.html) para determinar si un entero válido se convirtió del texto.

+0

En realidad estaba haciendo esto, pero me pareció feo obtener la cadena, luego analizar un número entero y luego verificar el estado devuelto, luego saltar a un ciclo while – Tanner

+0

Nunca dijiste que la estética era un problema :) Lo había olvidado sobre las funciones "is ____()", siempre me preocupo por algún caso marginal que se cuela por tus defensas si las usas. – jonsca

+0

Sí, acabo de encontrar uno en la respuesta que acepté. Ahora cambió a sscanf para realmente analizar la entrada. Con la entrada si ingresó un operador (+ - etc) arrojaría una excepción – Tanner

6

Pruebe esto, modifíquelo según sea necesario.

function answer = isint(n) 

if size(n) == [1 1] 
    answer = isreal(n) && isnumeric(n) && round(n) == n && n >0; 
else 
    answer = false; 
end 
-1

Pruebe este. Creo que es

% Assume false input at the beginning 
checkDice = 0; 

% As long as the input is false, stay in the loop 
while ~checkDice 
    % Take the input as a string 
    strDice = input('Enter the number of dice to roll: ', 's'); 
    % Convert string to number 
    dice = str2num(strDice); 

    % Length of dice will be 1 iff input is a single number 
    if length(dice) ~=1 
     checkDice = 0; 
    else 
     % Search for a positive integer 
     checkDice = ((dice>=1) && dice == floor(dice)); 
    end 

end 
2

Una forma más simple :) fácil de comprobar las propiedades de las entradas de la función/suministrados por el usuario es utilizar la función validateattributes. No sé cuándo se introdujo esta función por primera vez; puede que no haya estado presente cuando se formuló la pregunta por primera vez, pero creo que debe mencionarse aunque la pregunta sea anterior.

Si desea comprobar que una entrada proporcionada por el usuario es un escalar, positivo, no cero, número entero de valor real de cualquier tipo de dato numérico, puede hacerlo a través de un try-catch block así:

invalidInput = true; 
while invalidInput 
    num_dice = input('Enter the number of dice to roll: '); 
    try 
    validateattributes(num_dice, {'numeric'}, ... 
         {'scalar', 'integer', 'real', 'finite', 'positive'}) 
    invalidInput = false; 
    catch 
    disp('Invalid input. Please reenter...'); 
    end 
end 

Si se trata de entradas de función en lugar de una entrada proporcionada por el usuario, también puede hacer uso de la clase inputParser.

Cuestiones relacionadas