Исключения не работают на C ++ в XCode & amp; Окружения Borland [дубликаты]

Возможно, проблема в конфигурации почтового сервера, чтобы избежать подобных проблем или вам не нужно беспокоиться о проблеме с почтовым сервером, я рекомендую вам использовать PHPMailer , это плагин у которого есть все необходимое для отправки почты, единственное, что вы должны учесть, это иметь SMTP-порт (порт: 25 и 465), включен

require_once 'PHPMailer/PHPMailer.php';
require_once '/servicios/PHPMailer/SMTP.php';
require_once '/servicios/PHPMailer/Exception.php';

$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
try {
       //Server settings
       $mail->SMTPDebug = 0;                                 
       $mail->isSMTP();                                      
       $mail->Host = 'smtp.gmail.com';  
       $mail->SMTPAuth = true;                               
       $mail->Username = 'correo@gmail.com';                 
       $mail->Password = 'contrasenia';                           
       $mail->SMTPSecure = 'ssl';                          
       $mail->Port = 465;                                    

       //Recipients
       $mail->setFrom('correo@gmail.com', 'my name');    
       $mail->addAddress('destination@correo.com');               

       //Attachments
       $mail->addAttachment('optional file');         // Add files, is optional

       //Content
       $mail->isHTML(true);// Set email format to HTML
       $mail->Subject = utf8_decode("subject");
       $mail->Body    = utf8_decode("mail content");
       $mail->AltBody = '';
       $mail->send();
     }
     catch (Exception $e){
        $error = $mail->ErrorInfo;
     }

30
задан Ville-Valtteri 23 February 2016 в 11:02
поделиться

7 ответов

Вам нужно проверить это самостоятельно и выбросить исключение. Целое число, делящееся на ноль, не является исключением в стандартном C ++.

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

Исключения, перечисленные в Стандарт ISO:

namespace std {
    class logic_error;
        class domain_error;
        class invalid_argument;
        class length_error;
        class out_of_range;
    class runtime_error;
        class range_error;
        class overflow_error;
        class underflow_error;
}

, и вы думаете, что overflow_error идеально подходит для указания деления на ноль.

Но раздел 5.6 (C++11, хотя я не думаю, что это изменилось с предыдущей итерации) конкретно указывает:

Если второй операнд / или % равен нулю, поведение не определено.

Таким образом, может выбросить это (или любое другое) исключение. Он также может отформатировать ваш жесткий диск и смеяться насмешливо: -)


Если вы хотите реализовать такого зверя, вы можете использовать что-то вроде intDivEx в следующей программе:

#include <iostream>
#include <stdexcept>

// Integer division, catching divide by zero.

inline int intDivEx (int numerator, int denominator) {
    if (denominator == 0)
        throw std::overflow_error("Divide by zero exception");
    return numerator / denominator;
}

int main (void) {
    int i = 42;

    try {
        i = intDivEx (10, 2);
    } catch (std::overflow_error e) {
        std::cout << e.what() << " -> ";
    }
    std::cout << i << std::endl;

    try {
        i = intDivEx (10, 0);
    } catch (std::overflow_error e) {
        std::cout << e.what() << " -> ";
    }
    std::cout << i << std::endl;

    return 0;
}

Это выводит:

5
Divide by zero exception -> 5

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


Эквивалент % почти то же самое:

// Integer remainder, catching divide by zero.

inline int intModEx (int numerator, int denominator) {
    if (denominator == 0)
        throw std::overflow_error("Divide by zero exception");
    return numerator % denominator;
}
48
ответ дан paxdiablo 22 August 2018 в 03:49
поделиться
  • 1
    Спасибо, я искал случаи, когда система выдает исключение, возможно ли это в c ++? – user33424 25 May 2011 в 09:43
  • 2
    @ user33424, да, возможно, см. мой ответ, например, на std::bad_alloc, который вызывается new – iammilind 25 May 2011 в 09:46
  • 3
    хм, поэтому вам не нужно тщательно выбирать, когда вы решите использовать класс исключений, поскольку все они принимают одинаковый параметр. – user33424 25 May 2011 в 10:09
  • 4
    @user Но вы должны выбрать тот, который делает ваше намерение ясно о том, что пошло не так. Выбрасывание bad_alloc, например. Недействительный_аргумент - плохой дизайн. – RedX 25 May 2011 в 10:40
  • 5
    Поскольку доменом функции является множество допустимых входных данных, для которых определена функция, не было бы domain_error более уместным бросить здесь? – John H 14 March 2014 в 20:21

do i need to throw an exception or does the computer automatically throws one at runtime?

Вам нужно throw исключение самостоятельно и catch оно. например,

try {
  //...
  throw int();
}
catch(int i) { }

Или catch исключение, которое выдается вашим кодом.

try {
    int *p = new int();
}
catch (std::bad_alloc e) {
    cerr << e.what();
}

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

catch(...) {  // catch 'any' exception
}
-2
ответ дан iammilind 22 August 2018 в 03:49
поделиться
  • 1
    Деление на ноль - это неопределенное поведение. – GManNickG 25 May 2011 в 09:52
  • 2
    люди, которые не знают об этом свойстве существования (в Windows с более чем 20 лет и OSX), не должны отвечать здесь, ни голосовать, ни называть себя инженерами-программистами. – user 1 March 2016 в 18:45

Вы можете просто сделать assert(2 * i != i), который будет вызывать утверждение. Вы можете написать свой собственный класс исключений, если вам нужно что-то более интересное.

-4
ответ дан kay 22 August 2018 в 03:49
поделиться
  • 1
    -1 Мне действительно не нравится это решение. Как это легче, чем assert(i != 0)? Я не разбирался в пограничных делах, но если нет тривиального взгляда на то, что утверждение утверждается правильно, то вы не должны его выражать. – kay 15 July 2012 в 00:09
  • 2
    Кроме того, assert часто дезактивируется в производственном коде из-за присутствия NDEBUG - assert(), как правило, является единственным способом только для обнаружения проблем. В любом случае, бросая утверждение, not бросает исключение. Первый будет прервать вашу программу, а не генерировать то, что вы можете поймать. – paxdiablo 3 November 2015 в 02:47

Насколько я знаю, спецификации C ++ ничего не говорят о делении на ноль. Я считаю, что вам нужно сделать это сами ...

Строуструп говорит в «Проекте и эволюции C ++» (Addison Wesley, 1994), «события низкого уровня, такие как арифметические переполнения и делятся на ноль, предполагается, что они обрабатываются выделенным механизмом нижнего уровня, а не исключениями, что позволяет C ++ сопоставлять поведение других языков, когда дело касается арифметики, а также позволяет избежать проблем, возникающих на сильно конвейерных архитектурах, где такие события, как деление на ноль, являются асинхронными. "`

7
ответ дан Thanatos 22 August 2018 в 03:49
поделиться

Обновлено с комментариями ExcessPhase

GCC (по крайней мере, версия 4.8) позволит вам эмулировать это поведение:

#include <signal.h>
#include <memory>
#include <iostream>

int main() {
    std::shared_ptr<void(int)> handler(
        signal(SIGFPE, [](int signum) {throw std::logic_error("FPE"); }),
        [](__sighandler_t f) { signal(SIGFPE, f); });

    int i = 0;

    std::cin >> i;  // what if someone enters zero?

    try {
        i = 5/i;
    }
    catch (std::logic_error e) {
        std::cerr << e.what();
    }
}

Это устанавливает новый обработчик сигнала, который генерирует исключение , и shared_ptr для старого обработчика сигналов с пользовательской функцией «удаления», которая восстанавливает старый обработчик, когда он выходит из области видимости.

Вам необходимо скомпилировать, по крайней мере, следующие параметры:

g++ -c Foo.cc -o Foo.o -fnon-call-exceptions -std=c++11

Visual C ++ также позволит вам сделать что-то похожее:

#include <eh.h>
#include <memory>

int main() {
    std::shared_ptr<void(unsigned, EXCEPTION_POINTERS*)> handler(
        _set_se_translator([](unsigned u, EXCEPTION_POINTERS* p) {
            switch(u) {
                case FLT_DIVIDE_BY_ZERO:
                    throw std::logic_error("Divide by zero");
                ...
                default:
                    throw std::logic_error("SEH exception");
            }
        }),
        [](_se_translator_function f) { _set_se_translator(f); });

    int i = 0;

    try {
        i = 5 / i;
    } catch(std::logic_error e) {
        std::cerr << e.what();
    }
}

И, конечно же, вы можете пропустить все 11-ий смысл C ++ и поместить их в традиционный RAII-управляющая структура.

10
ответ дан Tom 22 August 2018 в 03:49
поделиться
  • 1
    Установка и восстановление обработчика сигнала должна использовать RAII! Также вы не можете предположить, что обработчик сигнала по умолчанию был тем, который вы временно заменили. – user 3 November 2015 в 18:46
  • 2
    Спасибо, @ExcessPhase, я обновил ответ, чтобы отразить это. – Tom 23 February 2016 в 15:35
  • 3
    При компиляции визуального кода c ++ в visual studio 2012 я получаю эту ошибку: & quot; FLT_DIVIDE_BY_ZERO ': необъявленный идентификатор & quot ;. Я включил «windows.h». Где я иду не так? – Nishant 15 July 2016 в 04:10
  • 4
    код должен быть исправлен. Есть ошибки. – kyb 25 May 2018 в 11:01
  • 5
    Я исправил версию GCC. У меня нет установки VC ++, чтобы проверить ее. – Tom 25 May 2018 в 15:47

Вы должны проверить, есть ли i = 0 и не делить потом.

(При необходимости после проверки вы можете выбросить исключение и обработать его позже).

Дополнительная информация: http://www.cprogramming.com/tutorial/exceptions.html

1
ответ дан Vadiklk 22 August 2018 в 03:49
поделиться

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

Пример:

#include <iostream>
using namespace std;

double division(int a, int b)
{
   if( b == 0 )
   {
      throw "Division by zero condition!";
   }
   return (a/b);
}

int main ()
{
   int x = 50;
   int y = 0;
   double z = 0;

   try {
     z = division(x, y);
     cout << z << endl;
   }catch (const char* msg) {
     cerr << msg << endl;
   }

   return 0;
}
0
ответ дан yask 22 August 2018 в 03:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: