Error входная строка имела неверный формат

Ошибка "Входная строка имела неверный формат" C# Решение и ответ на вопрос 359023

karakalpak

3 / 3 / 1

Регистрация: 27.11.2010

Сообщений: 161

1

Ошибка «Входная строка имела неверный формат»

01.10.2011, 17:11. Показов 134732. Ответов 23

Метки нет (Все метки)


Здравствуйте!
Нужна помощь! Изучаю C#. Пишу программу. Немогу понять ошибку. Выскакивает такое сообщение об ощибке: Входная строка имела неверный формат. Помогите пожалуйста.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
namespace Кафе
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
 
            comboBox1.Items.Add("Самса");
            comboBox1.Items.Add("Беляши");
            comboBox1.Items.Add("Hot-Dog");
            comboBox1.Items.Add("Гамбургер");
            comboBox1.Items.Add("Кола");
            comboBox1.Items.Add("Чай");
            comboBox1.Items.Add("Кофе");
 
            comboBox1.SelectedIndex = 0;
 
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            double n=0;
            double cena = 0;
            double summa;
 
            try 
            {
                n = Convert.ToDouble(textBox1.Text);
            }
            catch
            {
            MessageBox.Show("Введите правильные данные");
            }
          
            summa = Convert.ToDouble(textBox2.Text);
 
            switch (comboBox1.SelectedIndex)
            {
                case 0: cena = 600; break;
                case 1: cena = 500; break;
                case 2: cena = 1200; break;
                case 3: cena = 1500; break;
                case 4: cena = 600; break;
                case 5: cena = 300; break;
                case 6: cena = 500; break;
 
            }
            summa = cena * n;
 
            summa.ToString();
            
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            textBox1.Text = "";
            textBox2.Text = "";
 
        }
    }
}

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



kolorotur

Эксперт .NET

16930 / 12507 / 3286

Регистрация: 17.09.2011

Сообщений: 20,745

01.10.2011, 17:19

2

Цитата
Сообщение от karakalpak
Посмотреть сообщение

C#
1
2
3
4
5
6
7
comboBox1.Items.Add("Самса");
 comboBox1.Items.Add("Беляши");
 comboBox1.Items.Add("Hot-Dog");
 comboBox1.Items.Add("Гамбургер");
 comboBox1.Items.Add("Кола");
 comboBox1.Items.Add("Чай");
 comboBox1.Items.Add("Кофе");

И так есть хочется, а тут еще вы со своими беляшами

Цитата
Сообщение от karakalpak
Посмотреть сообщение

C#
1
summa = Convert.ToDouble(textBox2.Text);

Скорее всего ошибка выскакивает на этой строке.
Вероятно, во втором текстбоксе вы вводите значение, которое не парсится в десятичное число. Например, «2A.345».
Надо бы эту строчку перенести в блок try/cache, к парсу первого текстбокса.

Цитата
Сообщение от karakalpak
Посмотреть сообщение

C#
1
summa.ToString();

А это здесь зачем?



0



3 / 3 / 1

Регистрация: 27.11.2010

Сообщений: 161

01.10.2011, 17:22

 [ТС]

3

Цитата
Сообщение от kolorotur
Посмотреть сообщение

Вероятно, во втором текстбоксе вы вводите значение, которое не парсится в десятичное число. Например, «2A.345»

А точнее?



0



kolorotur

Эксперт .NET

16930 / 12507 / 3286

Регистрация: 17.09.2011

Сообщений: 20,745

01.10.2011, 17:37

4

Так а куда точнее?
Вот кусочек вашего кода:

Цитата
Сообщение от karakalpak
Посмотреть сообщение

C#
1
2
3
4
5
6
7
8
9
try 
 {
 n = Convert.ToDouble(textBox1.Text);
 }
 catch
 {
 MessageBox.Show("Введите правильные данные");
 }
summa = Convert.ToDouble(textBox2.Text);

Сначала вы считываете текст из textBox1 и перегоняете его в double. Если пользователь ввел не число, а какую-нибудь ерунду, то выскочит исключение FormatException. В вашем коде абсолютно правильно конвертирование текста в число вложено в блок try/catch чтобы в случае чего это исключение поймать и показать пользователю сообщение об ошибке.
Несколькими строчками ниже вы делаете то же самое, но конвертируете текст из textBox2 в переменную summa. Внимание, вопрос: почему во втором случае вы не отслеживаете возможный выброс исключения?
В случае, если пользователь введет ерунду в textBox2, ваш код не рассматривает такую ситуацию и исключение FormatException не будет поймано и должным образом обработано. В результате программа закрашится.

Можно сделать так:

C#
1
2
3
4
5
6
7
8
9
try 
 {
    n = Convert.ToDouble(textBox1.Text);
    summa = Convert.ToDouble(textBox2.Text);
 }
 catch
 {
    MessageBox.Show("Введите правильные данные");
 }



0



3 / 3 / 1

Регистрация: 27.11.2010

Сообщений: 161

01.10.2011, 17:46

 [ТС]

5

Цитата
Сообщение от kolorotur
Посмотреть сообщение

нимание, вопрос: почему во втором случае вы не отслеживаете возможный выброс исключения?

т.к я в своиствах поставил readonly
Вот сам проект Кафе.zip Все равно не делает расчет



0



kolorotur

Эксперт .NET

16930 / 12507 / 3286

Регистрация: 17.09.2011

Сообщений: 20,745

01.10.2011, 17:57

6

Ага, второй текстбокс у вас служит для отображения общей стоимости.
В данном случае другой вопрос: зачем перегонять его значение в переменную summa еще до того, как она просчитана? Эта строчка в таком случае вообще не нужна.
Попробуйте так:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
        private void button1_Click(object sender, EventArgs e)
        {
            double n=0;
            double cena = 0;
            double summa;
 
            try 
            {
                n = Convert.ToDouble(textBox1.Text);
            }
            catch
            {
            MessageBox.Show("Введите правильные данные");
            }
 
            switch (comboBox1.SelectedIndex)
            {
                case 0: cena = 600; break;
                case 1: cena = 500; break;
                case 2: cena = 1200; break;
                case 3: cena = 1500; break;
                case 4: cena = 600; break;
                case 5: cena = 300; break;
                case 6: cena = 500; break;
 
            }
            summa = cena * n;
 
            textBox2.Text = summa.ToString();
            
        }



1



karakalpak

3 / 3 / 1

Регистрация: 27.11.2010

Сообщений: 161

01.10.2011, 18:02

 [ТС]

7

Цитата
Сообщение от kolorotur
Посмотреть сообщение

В данном случае другой вопрос: зачем перегонять его значение в переменную summa еще до того, как она просчитана?

Правда зачем Работает! Спасибо!
А еще так можно сделать?:

C#
1
Label1.Text=summa.ToString("C")



0



Эксперт .NET

16930 / 12507 / 3286

Регистрация: 17.09.2011

Сообщений: 20,745

01.10.2011, 18:11

8

Цитата
Сообщение от karakalpak
Посмотреть сообщение

Label1.Text=summa.ToString(«C»)

Можно, но тогда надо либо указать в какой культуре проводить форматирование, либо учесть что по дефолту будет использована культура, указанная в региональных настройках компьютера пользователя. Так что у кого-то цена будет показываться в рублях, у кого-то в долларах, у кого-то в евро и т.д. Со всеми нюансами местного форматирования.



1



Tronium13

0 / 0 / 0

Регистрация: 16.03.2015

Сообщений: 15

16.03.2015, 15:57

9

C#
1
2
3
4
5
6
if(textBox1.Text=="" || textBox2.Text==""/*||textBox3.Text==""*/);
MessageBox.Show("Не все поля были заполнены", "Упс");
          
double result_double = (Convert.ToDouble(textBox1.Text) / 8) * (Convert.ToDouble(textBox2.Text) / 8);
double result = Convert.ToDouble(Math.Ceiling(result_double));
textBox5.Text = result.ToString();

после вывода сообщения «Что поля не заполнены», выдает ошибку — «Входная строка имела не верный формат», подскажите где ошибка

Ругается на 4 строку



0



kolorotur

Эксперт .NET

16930 / 12507 / 3286

Регистрация: 17.09.2011

Сообщений: 20,745

16.03.2015, 16:09

10

Цитата
Сообщение от Tronium13
Посмотреть сообщение

после вывода сообщения «Что поля не заполнены», выдает ошибку

Если определили, что ввод неправильный, то зачем потом пытаться этот неправильный ввод обрабатывать?

C#
1
2
3
4
5
if(textBox1.Text=="" || textBox2.Text=="")
{
   MessageBox.Show("Не все поля были заполнены", "Упс");
   return;
}

Сообщение с ошибкой «упс» в вашем коде, кстати, в любом случае будет выдавать.
Почему — попробуйте догадаться сами.



1



0 / 0 / 0

Регистрация: 16.03.2015

Сообщений: 15

16.03.2015, 16:20

11

вы правы, догадаться не смог…



0



Эксперт .NET

16930 / 12507 / 3286

Регистрация: 17.09.2011

Сообщений: 20,745

16.03.2015, 16:39

12

Цитата
Сообщение от Tronium13
Посмотреть сообщение

вы правы

В чем?
Я не говорил, что вы не сможете догадаться.

Цитата
Сообщение от Tronium13
Посмотреть сообщение

догадаться не смог

Посмотрите внимательней — там всего две строчки кода, где идет проверка и вывод сообщения.



0



0 / 0 / 0

Регистрация: 16.03.2015

Сообщений: 15

16.03.2015, 16:49

13

Цитата
Сообщение от kolorotur
Посмотреть сообщение

Сообщение от Tronium13
вы правы
В чем?

в том что будет появляться все равно

решить проблему так и не смог…даже гугл не смог помочь



0



Эксперт .NET

16930 / 12507 / 3286

Регистрация: 17.09.2011

Сообщений: 20,745

16.03.2015, 17:17

14

Цитата
Сообщение от Tronium13
Посмотреть сообщение

решить проблему так и не смог

Я, конечно, могу тупо указать на ошибку, но в данном случае это будет антипедагогично.
Уберите из первой строчки закомментированный мусор и внимательно посмотрите еще раз на условие и идущую после него инструкцию.



0



0 / 0 / 0

Регистрация: 16.03.2015

Сообщений: 15

16.03.2015, 17:34

15

Цитата
Сообщение от kolorotur
Посмотреть сообщение

но в данном случае это будет антипедагогично

я все понимаю, но найти не могу смысл ошибки моей, не в какую, может слишком глубоко капаю



0



kolorotur

Эксперт .NET

16930 / 12507 / 3286

Регистрация: 17.09.2011

Сообщений: 20,745

16.03.2015, 17:43

16

Цитата
Сообщение от Tronium13
Посмотреть сообщение

может слишком глубоко капаю

Мне тоже так кажется.

С ошибкой:

C#
1
2
if(textBox1.Text=="" || textBox2.Text=="");
MessageBox.Show("Не все поля были заполнены", "Упс");

Без ошибки:

C#
1
2
if(textBox1.Text=="" || textBox2.Text=="")
MessageBox.Show("Не все поля были заполнены", "Упс");



1



0 / 0 / 0

Регистрация: 16.03.2015

Сообщений: 15

16.03.2015, 17:49

17

Цитата
Сообщение от kolorotur
Посмотреть сообщение

Мне тоже так кажется.

-_- без комментариев

ps спасибо

подскажите тему с ошибками, по типу «Входная строка имела неверный формат.» выдает уже другую ошибку, по тому же коду…



0



115 / 116 / 52

Регистрация: 19.12.2014

Сообщений: 612

16.03.2015, 18:22

18

Tronium13,
При конвертировании в Double, из поля textbox убедитесь а правильно ли вы заполняли это поле?
Вот пример, в США десятичный разделитель это точка.
У нас в России запятая.
Поэтому все зависит как уже говорилось от региональных параметров, попробуйте для начала ввести число
к примеру 4,5, а после 4.5 и посмотрите, что получиться.



0



Tronium13

0 / 0 / 0

Регистрация: 16.03.2015

Сообщений: 15

16.03.2015, 23:07

19

Цитата
Сообщение от lokilo
Посмотреть сообщение

Tronium13,
При конвертировании в Double, из поля textbox убедитесь а правильно ли вы заполняли это поле?
Вот пример, в США десятичный разделитель это точка.
У нас в России запятая.
Поэтому все зависит как уже говорилось от региональных параметров, попробуйте для начала ввести число
к примеру 4,5, а после 4.5 и посмотрите, что получиться.

C#
1
2
3
4
5
6
7
8
9
if (textBox1.Text == null || textBox2.Text == null)
            {
                MessageBox.Show("Не все поля были заполнены", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            
                double result_double = (Convert.ToDouble(textBox1.Text) / 8) * (Convert.ToDouble(textBox2.Text) / 8);
                double result = Convert.ToDouble(Math.Ceiling(result_double));
                textBox5.Text = result.ToString();

я пытаюсь сделать расчет с пустыми полями, после чего получается такая ошибка

вот в коде, заполняя тексбокс 1 и 2, подсчет идет, если пытаюсь пройти с пустыми полями, (он должен выдать ошибку что поля не были заполнены), выдает ошибку в коде, на 7 строку



0



lokilo

115 / 116 / 52

Регистрация: 19.12.2014

Сообщений: 612

17.03.2015, 02:05

20

Tronium13,

C#
1
2
3
4
5
6
7
8
9
if (textBox1.Text == null || textBox2.Text == null)
            {
                MessageBox.Show("Не все поля были заполнены", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            
                double result_double = (Convert.ToDouble(textBox1.Text) / 8) * (Convert.ToDouble(textBox2.Text) / 8);
                double result = Convert.ToDouble(Math.Ceiling(result_double));
                textBox5.Text = result.ToString();

Вот ваш код, вы наверное не смотрите или не хотите внимательно смотреть у вас есть условие if, после него идет код, в него нужно ставить else, чтобы он выполнялся когда поля не пустые, а когда пустые не выполнялся

C#
1
2
3
4
5
6
7
8
9
10
11
12
if (textBox1.Text == null || textBox2.Text == null)
            {
                MessageBox.Show("Не все поля были заполнены", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            
else
               {
                double result_double = (Convert.ToDouble(textBox1.Text) / 8) * (Convert.ToDouble(textBox2.Text) / 8);
                double result = Convert.ToDouble(Math.Ceiling(result_double));
                textBox5.Text = result.ToString();
                 }



0



Данная статья относится к Microsoft Dynamics NAV для всех стран и всех языковых стандартов.

Симптомы

Предполагается запустить функцию службы Web с помощью параметра decimal в Microsoft Dynamics NAV 2009. При указании параметра decimal, возвращаемое значение повторяется. Если параметр отсутствует, появляется сообщение об ошибке неправильно:

«Входная строка имела неверный формат». Если параметр имеет тип Int, является ошибка «целое число не должно быть пустым.  Целое число отсутствует или является недопустимым в выражении».

Эта проблема возникает в следующих продуктах:

  • Microsoft Dynamics NAV 2009 R2

  • 2009 г. Пакет обновления 1 для Microsoft Dynamics NAV

Решение

Сведения об исправлении

Существует исправление от корпорации Майкрософт. Имеется раздел «Исправление доступно для загрузки» в верхней части этой статьи базы знаний. Если появляются проблемы загрузки установки исправления или другие вопросы технической поддержки, обратитесь к своему партнеру или зарегистрированы в плане поддержки непосредственно с корпорацией Майкрософт, можно обратитесь в службу технической поддержки Microsoft Dynamics и создайте новый запрос на обслуживание. Чтобы сделать это, посетите следующий веб-узел корпорации Майкрософт:

https://mbs.microsoft.com/support/newstart.aspxМожно также службу технической поддержки для Microsoft Dynamics по телефону с помощью этих ссылок для телефонов конкретной страны. Для этого посетите один из следующих веб-узлах корпорации Майкрософт:

Партнеры

https://mbs.microsoft.com/partnersource/support/Клиенты

Как получить исправление Microsoft Dynamics NAV или обновления файлов

После запроса исправления Microsoft Dynamics NAV, гиперссылка будет отправлено вам по электронной почте.

Это сообщение будет содержать гиперссылку и пароль. Можно использовать гиперссылки для загрузки исправления Microsoft Dynamics NAV или файлов обновления. Если щелкнуть гиперссылку, откроется диалоговое окно Загрузка файла — предупреждение безопасности . Затем вы предложение запустить, сохранить или отменить загрузку.

Если нажать кнопку выполнить, начнется процесс извлечения и загрузки. Необходимо указать папку для новых файлов и затем указать пароль.

Если нажать кнопку Сохранить, укажите путь для сохранения сжатого файла. При открытии сохраненного файла, вам будет предложено указать путь к файлам. Затем необходимо указать пароль, полученный в сообщении электронной почты.

Если нажать кнопку Отмена, процесс загрузки прекратится.

Установка исправления Microsoft Dynamics NAV или файл обновления

Обновления и исправления платформы Microsoft Dynamics NAV будут доступны как отдельные файлы. Чтобы установить Microsoft Dynamics NAV исправление или обновление, необходимо заменить существующие файлы установки Microsoft Dynamics NAV с исправление или обновление файлов. Чтобы сделать это, выполните следующие действия.

Шаг 1: Замените файлы в Microsoft Dynamics NAV классический клиент установки

В установке Microsoft Dynamics NAV классический клиент Замените следующие файлы с помощью исправления или обновления файла.

Нужна дополнительная помощь?

Входная строка имела неверный формат. В чём ошибка?

При выполнении этого куска кода происходит ошибка.

double d = double.Parse("1.1");
Console.WriteLine("Value of d: {0}", d);

Почему собственно неверный формат, вроде всё правильно.

P.S пример из книги Andrew Troelsen. Pro C# and .NET4.5


  • Вопрос задан

    более трёх лет назад

  • 23335 просмотров

А так:

double d = double.Parse("1,1");
Console.WriteLine("Value of d: {0}", d);

Все дело в локализации которая установлена в операционной системе. Если ru, то запитая, если eng, то точка.

Пригласить эксперта

Если вы точно уверены, что у вас всегда будет точка в качестве разделителя запятой, то вам проще всего будет задать инвариантную культуру.

double d = double.Parse("1.1", CultureInfo.InvariantCulture);

Если всегда запятая, но не уверены, что будет стоять русская локализация в системе:

double d = double.Parse("1,1", CultureInfo.GetCultureInfo("Ru-ru"));


  • Показать ещё
    Загружается…

09 февр. 2023, в 18:43

10000 руб./за проект

09 февр. 2023, в 18:25

5000 руб./за проект

09 февр. 2023, в 18:23

2500 руб./за проект

Минуточку внимания

Сообщение = Входная строка имеет неправильный формат. в C#

В первом цикле while, который я конвертирую в double, возникает следующее исключение:

Я не уверен, что пишу неправильно или как исправить эту проблему. Я читаю из файла csv. Я протестировал, чтобы убедиться, что данные передаются от переменной к переменной, и это так. данные считываются моим Streamreader и сохраняются в одномерных массивах, которые сохраняются в переменной, которую я использую для сравнения точек данных для определения всех пиков и впадин в наборе данных

Это моя программа:

Первое, что я сделал бы, это запустил это в отладчике и установил прерывание при возникновении этого исключения. Затем вы можете посмотреть значение, которое не удалось проанализировать.

Строка, которую вы пытаетесь преобразовать, не является допустимым двойным значением. Может проблема в культуре? проверьте, есть ли в числах правильный десятичный разделитель, соответствующий языку вашей системы. Запятая или точка.

Формы c голосовым вводом в React с помощью Speechly

Flatpickr: простой модуль календаря для вашего приложения на React

Что такое cURL в PHP? Встроенные функции и пример GET запроса

Ответы 2

Где-то в вашем CSV-файле есть значение, которое нельзя преобразовать в double. Чтобы избежать этого исключения, замените все ваши Convert.ToDouble на Double.TryParse . Это вернет true , если значение может быть проанализировано на double или false , если это невозможно.

Сказав это, остальная часть вашего кода не имеет смысла. Если вы посмотрите на эту часть, например:

[NBug] Входная строка имела неверный формат. #6900

The application crashes if the entered value has unexpected format.
E.g. Enter 0.5 instead of 0,5 (wrong decimal delimiter) or any string value.

Expected behaviour

The application correctly parses any decimap delimiter and shows error message if the entered value is not a number.

Steps to reproduce

Open plugin settings menu: Plugins -> Plugin settings
Select the «Find large files» plugin
Enter «0,5» (without quotes) into the «Find large files bigger than (Mb)» edit line.

Error Details

Additional information

Open the Settings dialog for the Find large files plugin.
Enter: 0.5

Environment

  • Git Extensions 3.1.1.6049
  • Build 2f87210
  • Git 2.22.0.windows.1
  • Microsoft Windows NT 10.0.17763.0
  • .NET Framework 4.7.3416.0
  • DPI 96dpi (no scaling)

The text was updated successfully, but these errors were encountered:

gerhardol commented Jul 8, 2019

To parse invariant is common, I can consider this to be a bug.
You get the same message if you enter garbage in the form

This is a shared control, but this seem to be the only where float or double is parsed.
A solution is to use invariant parsing.
Pushed a change, I will not add testcases to this though.

piroxiljin commented Jul 9, 2019 •

@RussKie All localization settings are set to Russian, except the default locale for non-unicode application, which is English (US).

Oh. And decimal separator is comma (,).

RussKie commented Jul 9, 2019

A fix maybe to parse like so:

gerhardol commented Jul 9, 2019

The culture is used correctly, you get the exception of you use other culture. Like decimal comma with English.

Invariant parsing can be used, see my commit. But you still get the exception with garbage so not much better. Validation should be done when leaving the text box.

Too much work to give any significant benefit for the complete fix. The invariant is simple but to add tests will be a pain.

Входная строка имеет неправильный формат в double.Parse

Я новичок в C #. Пытаюсь сделать калькулятор, но произошла следующая ошибка:

Входная строка была не в правильном формате.

Это краткое изложение кода:

Как преобразовать строку в двойной тип?

5 ответов

Чего вы пытаетесь достичь с помощью этого кода? Похоже, ваш алгоритм неверен.

Как говорили другие, этот код

Вызовет исключение, потому что пустая строка не может быть преобразована в Double!

Итак, мне интересно, почему вы сбросили свое поле. Я подумал об этом какое-то время, и, может быть, я понял, что ты пытаешься сделать. Допустим, вы вводите число в TextBox1. Затем вы нажимаете кнопку «-», чтобы вычесть, и затем вы хотите ввести второе число, чтобы просмотреть результат. Так ли это? Если это так, то написанный вами код не будет ждать вашего следующего ввода!

Фактически, когда вы нажимаете кнопку, она просто выполняет все написанные вами строки. Я бы написал вместо этого что-нибудь подобное.

РЕДАКТИРОВАТЬ: если строка пуста, это всегда будет вызывать исключения, поэтому я добавил элемент управления. Если строка пуста, значение становится нулевым.

Также помните, что метод Parse для выполнения преобразования полагается на культуру вашей операционной системы, поэтому попробуйте изменить свой код на

Вы также можете использовать

Метод для лучшей обработки исключений.

Поскольку вы очистили текстовое поле в предыдущей строке, преобразование Parse не выполняется.

Как он преобразует String.Empty в Double? Это неправильный способ. Например, если нажата кнопка «+», вы должны проверить, был ли уже номер. Если да, сложите числа и отобразите результат:

Похоже, что значение num2 следует извлекать из textbox2 , а не из textbox1 (вы устанавливаете textbox1.text как empty и пытаетесь разобрать его, чтобы снова удвоить)

Также не используйте Convert.ToDouble(textBox1.Text) напрямую. если пользователи вводят нечисловые значения, ваш код выйдет из строя. сначала проверьте, действительный ли это номер, всегда используйте doube.TryPrase()

Ваш код кажется трудным для понимания того, как используются button_13 и button_14;

Урок 9: Обработка исключений.

Основная цель урока.

1.Изучить основные принципы перехвата и обработки исключений.

2.Познакомиться с некоторыми операции работы с файловой системой.

.

Краткая справка.

Обработка исключений.

Исключительная ситуация (или исключение) — это ошибка, которая возникает во время выполнения программы. В C# реализован механизм, позволяющий перехватывать такие исключительные ситуации. Рассмотрим пример – программа запрашивает у пользователя ввод некоторого числа из консоли, но не факт, что пользователь введёт именно число и следующий код может привести к ошибке(исключению).

Console.WriteLine(«Введите число»);

int n = Convert.ToInt32(Console.ReadLine());

Если пользователь введёт нечисловое значение, исключение в вышеприведённом коде сгенерирует метод ToInt32. Например, пользователь вводит консоли строку «56 ф», эта строка не может быть преобразована в число с помощью метода ToInt32 и будет выброшено исключение System.FormatException. (Exception –

с англ. « исключение»).

Чтобы узнать какие исключения может генерировать тот или иной метод,

достаточно просто подвести курсор к соответствующему методу.

Видно, что метод ToInt32 может генерировать 2 разных исключения –

System.FormatException и System.OverflowException.

Исключение System.FormatException выбрасывается, когда была передана строка в неверном формате, например: “сто”, “50ъ”, “+-200” или “абсде”.

Т.е. код Convert.ToInt32(“двести”) выбросит исключение System.FormatException.

Исключение System.OverflowException выбрасывается, когда было передано слишком большое число (Overflow – с англ. « переполнение»).

Т.е. код Convert.ToInt32(“648476438746”) выбросит исключение System.

OverflowException, т.к. строка несмотря на то, что строка “648476438746“ имеет числовой формат – такое больше число не может быть представлено типом int.

Для того чтобы отловить исключение соответствующего типа и предотвратить появление ошибки в программе нужно воспользоваться конструкцией try..catch.(try – c англ. « пробовать», catch – с англ. « ловить»).

Console.WriteLine(«Введите число»); try

{

int n = Convert.ToInt32(Console.ReadLine()); }catch(FormatException ex)

{

Console.WriteLine(«Неверный формат числа!»);

}

Вслучае ввода нечислового значения при выполнении вышеприведённого кода

впрограмме не возникнет ошибки, а будет произведён переход в блок catch. Чтобы отлавливать исключения других типов, нужно добавить ещё один блок catch.

Console.WriteLine(«Введите число»); try

{

int n = Convert.ToInt32(Console.ReadLine()); }catch(FormatException ex)

{

Console.WriteLine(«Неверный формат числа!»); }catch(OverflowException ex)

{

Console.WriteLine(«Введённое число не умещается в диапазоне»); Console.WriteLine(«от {0} до {1}»,int.MinValue,int.MaxValue);

}

Если необходимо отловить все исключения, можно воспользоваться базовым

классом для всех исключений – классом Exception. В этом случае отлавливаются

исключения всех видов, однако нельзя узнать из-за чего именно возникло

исключение.

Console.WriteLine(«Введите число»); try

{

int n = Convert.ToInt32(Console.ReadLine()); }catch(Exception ex)

{

Console.WriteLine(«Ошибка!»); Console.WriteLine(«Информация об ошибке: {0}»,ex.Message);

}

Выбрасывание исключений.

Общий синтаксис для выбрасывания (т.е. генерации) исключения выглядит

следующим образом:

Throw НовыйЭкземпярКлассаException;

Пример:

Console.WriteLine(«Введите чётное число»); try

{

int n = Convert.ToInt32(Console.ReadLine());

if (n % 2 != 0) throw new Exception(«Вы ввели НЕЧЁТНОЕ число!»); Console.WriteLine(«Спасибо!»);

}

catch (Exception ex)

{

Console.WriteLine(«Ошибка: {0}», ex.Message);

}

Результаты работы программы:

Пользователь ввёл

Результат

3,,5

Ошибка: Входная строка имела неверный формат

35

Ошибка: Вы ввели НЕЧЁТНОЕ число!

36

Спасибо!

Учебное задание 2.1.

Создать программу упрощающую процесс очистки жесткого диска от « мусора» –

тяжелых и неиспользуемых файлов. Программа должна уметь сканировать определённую директорию (или диск) на наличие больших файлов (более 300Мб)

последнее обращение к которым было более 90 дней назад. Программа должна игнорировать системные файлы.

Технология выполнения учебного задания 2.1.

Шаг 1. Создайте новый проект консольного приложения, назовите его Lab23.

Шаг 2. .Для того чтобы использовать классы Directory, File, Path и другие без явного указания принадлежности к пространству имён System.IO укажем, что он будет использоваться по умолчанию (листинг 1).

using System;

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

using System.IO; namespace Lab23

{

class Program

Листинг 1

Шаг 3. С помощью метода Directory.GetFiles можно получить список всех файлов в заданной директории. Получим список всех файлов на диске “C”. В

дальнейшем можно усовершенствовать программу так, чтобы пользователь сам мог указывать директорию для сканирования.

Для определения размера файла будем использовать класс FileInfo (см листин

2).

static void Main(string[] args)

{

string[] files;

//получаем список файлов на диске C files = Directory.GetFiles(@»C:»);

//Перебираем все файлы…

for (int i = 0; i < files.Length; i++)

{

//Для определения размера файла и других его характеристик //используем класс FileInfo

FileInfo info = new FileInfo(files[i]); //если размер файла больше 300 МБ…

if (info.Length > 300 * 1024 * 1024)

{

Console.WriteLine(«{0} (размер {1} мегабайт)», files[i], info.Length/1024/1024);

}

}

Console.ReadKey();

}

Листинг 2

Шаг 4. Запустите программу, нажав клавишу F5, убедитесь, что программа

работает.

Шаг 5. Программа выводит список всех файлов на диске C, размер которых превышает 300Мб, программа перечисляет все файлы в корне диска (даже скрытые и системные). Системные файлы удалять небезопасно, даже если к ним не было обращения в течении 90 дней – исключим эти файлы из результатов поиска.

Для этого воспользуемся свойством Attributes класса FileInfo. Свойство Attributes

имеет тип перечисления FileAttributes, само перечисление содержит следующие элементы (атрибуты).

public enum FileAttributes

{

ReadOnly = 1,

Hidden = 2,

System = 4, Directory = 16, Archive = 32, Device = 64, Normal = 128, Temporary = 256, SparseFile = 512,

ReparsePoint = 1024, Compressed = 2048, Offline = 4096, NotContentIndexed = 8192, Encrypted = 16384,

}

Обратите внимание, что каждому элементу в перечислении соответствуют не числа по порядку, а степени двойки (21, 22, 23, 24 и.т.д.). Это сделано для того, чтобы файл мог содержать не один, а несколько атрибутов. Если представить все эти числа в двоичной системе, получим:

ReadOnly

00000000000000000000000000000001

1

Hidden

00000000000000000000000000000010

2

System

00000000000000000000000000000100

4

Directory

00000000000000000000000000001000

8

Archive

00000000000000000000000000010000

16

Если файл имеет несколько атрибутов, например: архивный + только для чтения

+ скрытый, мы можем объединить каждый из этих атрибутов с помощью поразрядного ИЛИ.

1 ИЛИ 2 ИЛИ 16 = 19

В двоичной системе это будет выглядеть следующим образом:

00000000000000000000000000010011

Т.е. в двоичном представлении у числа 19 установлены только те биты, которые отвечают за соответствующие атрибуты.

Чтобы узнать, что у файла установлен конкретный атрибут можно воспользоваться следующим приёмом:

FileInfo info = new FileInfo(@»C:1.txt»);

if ((info.Attributes & FileAttributes.System) != 0)

{

Console.WriteLine(«У файла установлен атрибут Системный»);

}

Чтобы узнать дату последнего обращения к файлу нужно воспользоваться свойством LastAccessTime класса FileInfo.

Добавим функционал игнорирующий системные файлы и учитывающий файлы последнее обращение к которым было более 90 дней назад (листинг 3).

for (int i = 0; i < files.Length; i++)

{

//Для определения размера файла и других его характеристик //используем класс FileInfo

FileInfo info = new FileInfo(files[i]);

//если файл не является системным И //с момента последнего обращения к файлу прошло более 90 дней И //размер файла более 300 мегабайт

if (((info.Attributes & FileAttributes.System) == 0) && ((DateTime.Nowinfo.LastAccessTime).Days>90) && (info.Length > 300 * 1024 * 1024))

{

//Выводи информацию о файле в консоль

string name = Path.GetFileName(files[i]); Console.WriteLine(«{0} (размер {1} мегабайт)», name,

info.Length/1024/1024);

}

}

Листинг 3

Шаг 6. На данный момент программа перечисляет все файлы только в корне диска C, без учёта вложенных директорий. Для того, чтобы программа перечисляла все файлы с учётом вложенных поддиректорий удобно будет воспользоваться механизмом рекурсивных вызовов.

Идея в следующем, создаётся некоторая функция (например, EnumDir)

принимающая 1 аргумент – директорию, которую надо просканировать.

Внутри функции прописан следующий функционал:

1.Получаем список файлов в указанной директории (заданной аргументом)

2.Определяем размер файла, дату последнего обращения, принимаем решение выводить файл в консоль или нет.

3.Получаем список всех директорий в указанной директории (заданной аргументом)

4.В цикле для каждой директории из списка вызываем функцию EnumDir

ВС# функция может вызвать сама себя. Этот процесс называется рекурсией, а

функция, который вызывает себя, называют рекурсивной.

Вобщем случае рекурсия — это процесс определения чего-либо с использованием самого себя.

Вынесем реализованный функционал в отдельный метод, назовём его

EnumDir(см листинг 4).

static void Main(string[] args)

{

//вызываем функцию EnumDir EnumDir(@»C:»); Console.ReadKey();

}

static void EnumDir(string dir) {//начало функции EnumDir

string[] files;

//получаем список файлов для директории dir files = Directory.GetFiles(dir); //Перебираем все файлы…

for (int i = 0; i < files.Length; i++)

{

//Для определения размера файла и других его характеристик //используем класс FileInfo

FileInfo info = new FileInfo(files[i]); //если файл не является системным И

//с момента последнего обращения к файлу прошло более 90 дней И

//размер файла более 300 мегабайт

if (((info.Attributes & FileAttributes.System) == 0) && ((DateTime.Now — info.LastAccessTime).Days > 90) && (info.Length > 300 * 1024 * 1024))

{

//Выводи информацию о файле в консоль string name = Path.GetFileName(files[i]);

Console.WriteLine(«{0} (размер {1} мегабайт)», name, info.Length / 1024 / 1024);

}

}

//получаем список поддиректорий для директории dir string[] dirs = Directory.GetDirectories(dir);

//для каждой поддиректории вызываем функцию EnumDir (рекурсия) for (int i = 0; i < dirs.Length; i++)

{

EnumDir(dirs[i]);

}

}//конец функции EnumDir

Листинг 4

Шаг 7. Запустите программу, нажав клавишу F5. При запуске программы с большой долей вероятности будет выдано исключение:

System.UnauthorizedAccessException « Отказано в доступе по пути «C:XXXXXX»

На диске существуют директории для которых у пользователя нет прав на просмотр содержимого, это порождает такое исключение. Чтобы избежать этого можно воспользоваться конструкцией try..catch (см краткую справку). Код реализующий данный функционал приведён в листинге 5.

static void EnumDir(string dir) {//начало функции EnumDir

string[] files;

//пытаемся получить список файлов для директории dir try

{

files = Directory.GetFiles(dir); }catch(Exception e)

{

//если возникло исключение пишем информацию об ошибке Console.WriteLine(«Невозможно получить список файлов из {0}»,

dir); //и выходим из функции return;

}

//Перебираем все файлы…

for (int i = 0; i < files.Length; i++)

Листинг 5

Шаг 8. Запустите программу, нажав клавишу F5. Убедитесь, что программа

работает.

Контрольные вопросы.

1.Каким образом можно скопировать файл из одной директории в другую ?

2.Каким образом можно проверить, что файл с заданным именем существует на диске?

3.Каким образом можно получить список файлов для заданной директории ?

4.Что такое исключительная ситуация ?

5.Каким образом можно обрабатывать исключительные ситуации ?

6.Что такое рекурсия ?

Самостоятельное задание 2.1.

Напишите программу, которая сканирует некоторую папку (задаётся

пользователем) с учётом поддиректорий, все хранящиеся в ней файлы сортируются

по следующему принципу:

1.Все видеофайлы помещаются в папку Видео (видеофайлами считать файлы имеющие расширение avi, wmv, mkv, mp4)

2.Все аудиофайлы помещаются в папку Аудио (аудиофайлами считать файлы имеющие расширение wav, mp3, mid, wma, flac)

3.Все графические файлы помещаются в папку Изображения (графическими

файлами считать файлы расширение jpg, jpeg, png, gif, bmp)

Директории Видео, Аудио и Изображения должны создаваться в папке, указанной пользователем для сканирования. Для создания директории использовать метод

Directory.CreateDirectory.

Для определения расширения файла воспользоваться методом Path.GetExtension.

Для перемещения файлов используется метод File.Move.

Соседние файлы в папке Методичка (1 сем)

  • #
  • #
  • #
  • #
  • #
  • #

Понравилась статья? Поделить с друзьями:
  • Error x reader fanfiction
  • Error x nightmare фанфик
  • Error x ink yaoi 18 comic
  • Error x ink kids
  • Error x fresh yaoi