1

我正在尝试验证 ID。

ManejadorTickets在其中调用了这个类-除其他外-我调用了验证ID的方法(ID是Cedula,类似于美国的SSN)。

    public void venderTicket ()
    {
        // more code...

        Console.Write("\nCedula: ");
        string cedula = Validador.validarCedula(Console.ReadLine().Trim());

        // more code...
    }

这是我validarCedulaValidador课堂上的方法。

public static String validarCedula (string cedula)
        {
            // Limpiar la entrada de caracteres extraños
            cedula = cedula.Replace("-", "");
            cedula = cedula.Replace(" ", "");

            // Debe tener 11 caracteres
            if (cedula.Length != 11)
            {
                Impresor.imprimirOpExitosa(cedula.Length.ToString());
                Impresor.imprimirError("La cedula debe tener 11 digitos", "Cedula: ");
                validarCedula(Console.ReadLine().Trim());
            }

            // Todos los caracteres deben ser numeros
            char[] arrayLetras = cedula.ToCharArray();
            foreach (char c in arrayLetras)
            {
                if (NUMEROS.IndexOf(c) == -1)
                {
                    Impresor.imprimirError("Todos los caracteres deben ser numericos." +
                                            " Los guiones o espacios no se toman en cuenta.", "Cedula: ");
                    validarCedula(Console.ReadLine().Trim());

                }
            }

            return cedula;
        }

上述方法消除了输入中的连字符和空格。还要检查输入是否正好有 11 个字符以及所有字符是否都是数字。

注意:NUMBERS 是我在课程开始时声明的常量 private const string NUMEROS = "0123456789";

但是当我运行程序时,输入一个错误的值作为Cedula(测试我的验证方法),例如“foo”,它会发生应该发生的事情(再次询问该值)。到目前为止一切顺利,现在当我输入正确的值,例如 00114905656(所有数字和 11 位数字)时,它再次要求输入一个值,这不应该发生,因为最后输入的值是正确的。

我尝试调试我的应用程序,我看到该方法按应有的方式执行,但是当编译器执行语句return cedula;(方法中的最后一句)时,它会跳转到 validarCedula(Console.ReadLine().Trim()); 语句中的第一个if (cedula.Length != 11)语句。我不明白为什么会这样。当return执行该方法时,该方法应该完成。

4

3 回答 3

4

你是validarCedula从自身内部呼唤。这称为递归。

尝试从头开始。查看调用堆栈窗口。

我认为您需要对程序进行一些重组。

尝试实现validarCedula更多这样的:

static bool validarCedula(string cedula) {
   // do your string replace here
   // if it's ok, return true
   // if it's bad, return false.  
   // do not call validarCedula from here!      
}

然后在您的vendorTicket函数中执行此操作,因此您仍然可以让它重新提示,直到它通过:

string cedula;
bool ok = false;
while (!ok) {
    Console.Write("\nCedula: ");
    cedula = Console.ReadLine().Trim();
    ok = validarCedula(cedula);
}
于 2012-06-15T03:31:02.400 回答
1

我认为您调用函数的想法仍然与过程编程范式不一致。

当你调用一个函数时,你可能仍然认为它是“跳转到那个函数”。然而,真正发生的是它会“跳转到该函数并在完成后返回”。跳回是程序回到它离开的地方的部分。

于 2012-06-15T03:38:12.113 回答
0

您的 validarCedula 方法正在被递归调用,因此当它命中return cedula;程序控制​​时,它会返回到调用堆栈更下方的上一个调用。

于 2012-06-15T03:41:43.893 回答