2012-06-27 30 views
6

Tôi vẫn là người mới bắt đầu lập trình bằng các ngôn ngữ lập trình bậc cao, vì vậy tôi không biết đây có phải là giải pháp dễ dàng hay không, nhưng tôi rất vui khi được học. Tôi đã lập trình một chương trình báo động nhỏ trong C# cho phép người dùng nhập vào trong bao nhiêu giây báo thức cần phải tắt. Nó hoạt động hoàn hảo, nhưng đầu vào mà người dùng cần đưa ra phải là một số. Khi người dùng nhập bất kỳ dạng văn bản nào, chương trình sẽ bị treo. Bây giờ, làm thế nào tôi có thể ngăn chặn người dùng nhập văn bản, và gọi một chức năng hoặc làm điều gì đó khác khi người dùng thực hiện, thay vì chương trình chỉ bị lỗi?Làm thế nào để ngăn chặn một số hình thức đầu vào nhất định khi viết các phương thức?

Đây là mã tôi có bây giờ:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace Test 
{ 
    class Alarm 
    { 
     public static void play() 
     { 
      int sec; 
      sec = Convert.ToInt16(Console.ReadLine()); 

      for (int i = 0; i < seconds; ++i) 
      { 
       System.Threading.Thread.Sleep(1000); 
      } 

      for (int i = 0; i < 10; i++) 
      { 
       Console.Beep(); 
      } 
     } 
    } 
} 
+0

Vâng, ngoài đầu của tôi, bạn có thể sử dụng 'try'' catch' quanh chuyển đổi và xử lý ngoại lệ theo ý bạn, ví dụ yêu cầu họ nhập lại giá trị. – user17753

+3

Trên một ghi chú riêng biệt, 'int' là một' Int32' không phải là một 'Int16'. 'short' là bí danh cho' Int16' –

+0

@JustinPihony Tôi thậm chí không biết về điều đó. Tôi đã chấp nhận tất cả các câu trả lời từ quá khứ đã giúp tôi. Cảm ơn vì tiền hỗ trợ. :) – DutchLearner

Trả lời

11

Bạn nên hoàn thành một tấm séc trước khi chuyển đổi:

int sec; 

if (int.TryParse(Console.ReadLine(), out sec) 
{ 
    // this is valid continue 
} 
else 
{ 
    // show error highlighting that entry must be a number 
} 

int.TryParse sẽ trả về một boolean làm nổi bật cho dù đầu vào là được phân tách đến một int. Nó cũng sẽ đặt biến số sec của bạn thành giá trị nếu thành công.

+0

Điều đó có hiệu quả, cảm ơn rất nhiều! Tôi chỉ cần đặt tất cả trong một vòng lặp while và tạo ra một giá trị Boolean đánh giá xem chức năng có thể kết thúc hay không, và đó là nó. : D – DutchLearner

1

Bạn nên sử dụng một phương pháp thử phân tích cú pháp.

Something như thế này:

int number; 
    bool result = Int32.TryParse(Console.ReadLine(), out number); 

Nếu kết quả là đúng, sau đó nó đã được phân tích thành công nó, có nghĩa là nó là một số nguyên. Nếu không, nó đã thất bại, có nghĩa là nó không phải là một số nguyên.

Sau đó, bạn có thể sử dụng số làm giá trị được phân tích cú pháp làm int32 của bạn.

0

thay

sec = Convert.ToInt16(Console.ReadLine()); 

với

try { 
    sec = Convert.ToInt16(Console.ReadLine()); 
} 

catch(Exception e){ 
    Console.Writeline(" Enter numbers only"); 
} 
+6

KHÔNG !, TryParse có lý do, không sử dụng ngoại lệ để kiểm soát luồng thông thường. –

+0

@Scott: đúng. ném ngoại lệ là đắt hơn. Tránh nó khi bạn có thể – codingbiz

+0

Không chắc chắn về chi phí nhưng, nó loại bỏ bổ sung nếu tuyên bố – madhairsilence

7

Bạn có thể lặp vô thời hạn cho đến khi người dùng nhập vào một số:

int number = 0; 
while(!Int32.TryParse(Console.ReadLine(), out number)) 
{ 
    Console.WriteLine("Please input a number."); 
} 

Int32.TryParse lợi nhuận false nếu chuyển đổi thất bại, thay vì ném một ngoại lệ và nếu thành công trả về kết quả tôi n tham số out thứ hai.

0

Những gì bạn đang cố gắng làm thường được gọi là Input Validation. Trong trường hợp của bạn, bạn cần phải kiểm tra xem họ đã nhập một số chưa trước khi phân tích cú pháp. Int16 có chức năng TryParse sẽ giúp bạn.

1

Mọi người đã trả lời ở đây. Tôi thích làm điều đó như là một extension method để tôi có thể gọi nó ở rất nhiều nơi.

public static bool IsNumeric(this string theValue) 
{ 
    long retNum; 
    return long.TryParse(theValue, System.Globalization.NumberStyles.Integer, 
      System.Globalization.NumberFormatInfo.InvariantInfo, out retNum); 
} 

Sau đó, tôi sẽ gọi nó như thế này

if(Console.ReadLine().IsNumeric()) 
{ 
    //The value is numeric. You can use it  
} 
0

Thêm một chức năng riêng biệt mà sử dụng một câu lệnh try để bắt lỗi đó là sản xuất khi cố gắng của bạn để bí mật một chuỗi không hợp lệ để một số nguyên.

int readInput() 
{ 
    int sec; 
    while(true) 
    { 
     try 
     { 
      sec = Convert.ToInt16(Console.ReadLine()); 
      return sec; 
     } 
     catch(Exception e) 
        { 
          Console.WriteLine("Enter an integer!"); 
        } 
    } 
    return 0; 
} 
+0

Bạn không muốn làm điều này ... Xử lý ngoại lệ để tạo thành một phần của luồng điều khiển tương tự như sử dụng các câu lệnh goto không cục bộ trên toàn bộ mã của bạn. – Blueberry

0

Nếu bạn muốn làm một cái gì đó hơn tao nhã hơn hiển thị một thông báo lỗi và yêu cầu người dùng nhập lại dữ liệu, bạn có thể thử chế biến mỗi tổ hợp phím khi nó xảy ra với Console.Readkey() và từ chối chúng nếu sẽ cho kết quả trong một chuỗi đó không phải là một con số.

Tôi đã làm điều gì đó như thế này năm trước trong TurboPascal.

Đây là mã giả được viết từ bộ nhớ nhưng sẽ giúp bạn đi đúng hướng. Nếu bạn cần lấy các giá trị dấu phẩy động cũng như các số nguyên hoặc cả số âm và số dương, bạn sẽ cần phải thêm nhiều logic hơn để xử lý các trường hợp đó.

string enteredText = ""; 
char key; 
bool done = false; 
while (!done) 
{ 
    key = Console.ReadKey(); 
    if (key is number) 
     enteredText += key; 
    else if (key is backspace) 
    { 
     //remove the last char from enteredText. Handle case where enteredText has length 0 
     Console.Write(backspace); 
    } 
    else if ((key is enter) && (enteredText.Length > 0)) 
     done = true; 
    else 
    { 
     // invalid char. 
     //MSDN says the char is echoed to the console so remove it 
     Console.Write(backspace); 
     //Beep at the user? 
    } 
} 
Các vấn đề liên quan