Функции в c ++

Ввиду функции, чтобы читать файл: Как я могу делать для того, чтобы, сделав вызов функции в главной, этой программе, он закрылся, когда файл не существует?

На данный момент я считаю сделанным это:

int leer_correo (int cart[], int certif[], int paq[]){
    FILE *fe;
    int i, anyo, total[ANYOS];
    if((fe=fopen("correo.txt", "r"))==NULL){
        printf("Error\n");
        return -1;
    }

    for(i=0 ; i<ANYOS ; i++)
        fscanf(fe, "%d%d%d%d", &anyo, &cart[i], &certif[i], &paq[i]);
    total[anyo-1900]=cart[anyo-1900]+certif[anyo-1900]+paq[anyo-1900];
    return 0;
}

void main(){
    int opc, cart[ANYOS], certif[ANYOS], paq[ANYOS];    
    leer_correo(); // Llamar a la función leer correo
    // Si hay error: terminar el programa
}
0
задан 16.11.2016, 12:58
3 ответа

Ты был должен доводить до сведения, используешь ли ты C или C ++, etiquta говорит C ++, но твой код принадлежит ANSI C.

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

#define NO_CORREO         -1
#define RESULTADO_NOFILE   1

void main() // Cambia el tipo de 
{
    int opc, cart[ANYOS], certif[ANYOS], paq[ANYOS];    
    if( leer_correo() == NO_CORREO ) // Llamar a la función leer correo
        exit(RESULTADO_NOFILE);      // Salida con código 1

    // Haz el resto de cosas que tengas que hacer.
}
1
ответ дан 24.11.2019, 12:35

У тебя есть несколько способов сообщать ошибку:

Использовать код ошибки

Это может делаться с #define или с enum. Мое личное предпочтение было бы вторым выбором по нескольким причинам:

  • Перечисленные производят различную идентификацию для каждого элемента автоматически, уменьши риск имения повторенных идентификаторов
  • Начиная с C ++ 11 (видеть третий пример), возможно предоставлять сильный tipado перечисленным. Большое преимущество в том, чтобы включать эту функцию состоит в том, что мы предоставляем более надежный код.

Пример с #define:

#define OK 0
#define FILE_NOT_FOUND 1
#define ANOTHER 2
// ...

int TestFunc()
{
  return FILE_NOT_FOUND;
}

int main()
{
  switch( TestFunc() )
  {
    case OK:
      std::cout << "Ok\n";
      break;

    case FILE_NOT_FOUND:
      std::cout << "Fichero no encontrado\n";
      break;

    // ...
  }
}

Пример с enum:

enum TestFuncReturn
{
  OK,
  FILE_NOT_FOUND,
  ANOTHER,
  // ...
};

TestFuncReturn TestFunc()
{
  return FILE_NOT_FOUND;
}

int main()
{
  switch( TestFunc() )
  {
    case OK:
      std::cout << "Ok\n";
      break;

    case FILE_NOT_FOUND:
      std::cout << "Fichero no encontrado\n";
      break;

    // ...
  }
}

Пример с enum в C ++ 11:

enum class TestFuncReturn
{
  OK,
  FILE_NOT_FOUND,
  ANOTHER,
  // ...
};

TestFuncReturn TestFunc()
{
  return TestFuncReturn::FILE_NOT_FOUND;
}

int main()
{
  switch( TestFunc() )
  {
    case TestFuncReturn::OK:
      std::cout << "Ok\n";
      break;

    case TestFuncReturn::FILE_NOT_FOUND:
      std::cout << "Fichero no encontrado\n";
      break;

    // ...
  }
}

Исключения:

Использовать коды ошибки имеет несколько недостатков:

  • они занимают return функции, а следовательно, чтобы возвращать добавочную информацию, он касается прибегать к устройствам как параметры из-за ссылки или к использованию std::pair или std::tuple.
  • Часто функция, которая получает сообщение ошибки, ничего не может делать из-за самой себя, чтобы возвращать ситуацию, касается пропагандировать ошибку вверх и это вызывает, что быть нужный иметь специальную заботу для того, чтобы различные сообщения ошибки не solapen.
  • Возвращать код ошибки от случая к случаю приходит в голову недостаточно для того, чтобы, например, сообщить пользователю относительно проблемы (какой файл он побил козырем?: Почему я мотивирую?: Есть что-то больше, чем быть нужный иметь в виду?).

Чтобы замещать эти недостатки существуют exepciones. Исключения могут (и они должны бы) быть объектами, что позволяет использовать возможность характерные для наследства, полиморфизма и encapsulación, чтобы предоставлять всю информацию, которая необходима, чтобы мочь восстанавливаться от ошибки.

Пример C ++ 98:

class FileNotFoundException : public std::exception
{
  public:

    FileNotFoundException(const std::string& mensaje)
      : m_error(mensaje)
    { }

    const char* what() const
    { return m_error.c_str(); }
  private:

    std::string m_error;
};

class AnotherException : public std::exception
{
  public:

    AnotherException (const std::string& mensaje)
      : m_error(mensaje)
    { }

    const char* what() const
    { return m_error.c_str(); }
  private:

    std::string m_error;
};

void TestFunc()
{
  throw FileNotFoundException("No se pudo encontrar el fichero notas.txt");
}

int main()
{
  try
  {
    TestFunc();
  }

  catch( const std::exception& exc )
  {
    std::cout << "Error: " << exc.what();
  }
}

Пример C ++ 11:

class FileNotFoundException : public std::exception
{
  public:

    FileNotFoundException(std::string const& mensaje) noexcept
      : m_error(mensaje)
    { }

    const char* what() const noexcept override
    { return m_error.c_str(); }
  private:

    std::string m_error;
};

class AnotherException : public std::exception
{
  public:

    AnotherException (std::string const& mensaje) noexcept
      : m_error(mensaje)
    { }

    const char* what() const noexcept override
    { return m_error.c_str(); }

  private:

    std::string m_error;
};

void TestFunc()
{
  throw FileNotFoundException("No se pudo encontrar el fichero notas.txt");
}

int main()
{
  try
  {
    TestFunc();
  }

  // Solo captura FileNotFoundException
  catch( const FileNotFoundException& exc )
  {
    std::cout << "Error de fichero: " << exc.what();
  }

  // Captura cualquier excepción que herede de std::exception
  // excepto FileNotFoundException, que está capturada en el catch anterior
  catch( const std::exception& exc )
  {
    std::cout << "Error: " << exc.what();
  }
}

Примеры с enum или #define я не буду помещать тебя, потому что уже у тебя есть другие ответы покрывая эту область.

Я помещаю тебе пример присоединяя исключения. Также я ретушировал немного код, чтобы это оставлять больше, согласно которому он ожидается кода C ++ более или менее современный (отсутствие сырых договоренностей, переменных, объявленных в Вашем моменте, использовании собственного ввода / вывода C ++...). Единственным, что я не изменил, является использование файла... конечно, помнит, что ты должен закрывать файл перед тем, как оставлять функцию.

class FileNotFoundException : public std::exception
{
  public:

    FileNotFoundException(const std::string& mensaje)
      : m_error(mensaje)
    { }

    const char* what() const
    { return m_error.c_str(); }
  private:

    std::string m_error;
};

struct Datos
{
  cart;
  certif;
  paq;
};

typedef std::array<Datos,ANYOS> VectorDatos;

VectorDatos leer_correo ()
{
  VectorDatos datos;
  FILE *fe;

  if((fe=fopen("correo.txt", "r"))==NULL){
    throw FileNotFoundException("Error al abrir correo.txt");
  }

  for(int i=0 ; i<ANYOS ; i++)
  {
    int anyo;
    Datos& item = datos[i];
    fscanf(fe, "%d%d%d%d", &anyo, &item.cart, &item.certif, &item.paq);
  }

  fclose(fe);

  return datos;
}

void main(){
  std::array<Datos,ANYOS> datos;

  try
  {    
    datos = leer_correo(); // Llamar a la función leer correo
  }

  catch( const FileNotFoundException& exc )
  {
    std::cout << "Error: " << exc.what();

    // Si otro programa está esperando a que éste devuelva una respuesta
    // entonces el valor de este código es importante. En caso contrario
    // es irrelevante.
    return -1; 
  }

  // Resto del main
  // ...
}

Код должен бы быть совместим с C ++ 98. Я попробовал это сделать так кстати, потому что видя твой код я не думаю, что ты составляешь с C ++ 11 или C ++ 14.

1
ответ дан 24.11.2019, 12:35

Ты был бы должен, в бы main, проверять результат mГ©todo leer_corre, чтобы видеть, была ли ошибка или не следующей формы:

    #define ERROR_READ_FILE      -1
    #define SUCCESS_READ_FILE    1

    int leer_correo (int cart[], int certif[], int paq[]){
        FILE *fe;
        int i, anyo, total[ANYOS];
        if((fe=fopen("correo.txt", "r"))==NULL){
            printf("Error\n");
            return ERROR_READ_FILE;
        }

        for(i=0 ; i<ANYOS ; i++)
            fscanf(fe, "%d%d%d%d", &anyo, &cart[i], &certif[i], &paq[i]);
        total[anyo-1900]=cart[anyo-1900]+certif[anyo-1900]+paq[anyo-1900];
        return SUCCESS_READ_FILE;
    }

    void main(){
        int opc, cart[ANYOS], certif[ANYOS], paq[ANYOS];    
        if (leer_correo() == ERROR_READ_FILE) // Llamar a la función leer correo
            exit(0); // Si hay error: terminar el programa
    }

Надеялся, что он тебе полезен!

0
ответ дан 24.11.2019, 12:35

Теги

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