Thread: Failure in file inclusion

  1. #1
    Registered User
    Join Date
    Nov 2006
    Location
    Coimbra, Portugal
    Posts
    64

    Failure in file inclusion

    I'm currently studying wxWidgets programming, and everything's going just fine... Except for one part, that is. The project I'm working on is a Celsius to Fahrenheit converter. So far, I have three files: CelsiusFahrenheit.cpp, Utilitarios.h, Utilitarios.cpp, the first of which contains the main program. Here's the code:

    CelsiusFahrenheit.cpp

    Code:
    #define CELSIUS_BUTTON_ID 1
    #define FAHRENHEIT_BUTTON_ID 2
    #include "wx/wx.h"
    
    #include "Utilitarios.h"
    #include <string>
    using namespace std;
    
    class CelsiusFahrenheit: public wxApp {
      public:
        //Variaveis globais
        wxTextCtrl* celsius_text;
        wxTextCtrl* fahrenheit_text;
        //Metodo OnInit, iniciador da aplicacao
        bool OnInit() {
          //Inicializa a janela
          wxSize* tamanho_janela = new wxSize(640,480);
          wxString* titulo = new wxString("Conversor Celsius-Fahrenheit-Celsius");
          wxFrame* janela = new wxFrame(NULL, -1, *titulo, wxDefaultPosition, *tamanho_janela);
          //Inicializa os controlos de texto
          int celsius_text_x = 0;
          int celsius_text_y = 0;
          int fahrenheit_text_x = celsius_text_x;
          int fahrenheit_text_y = celsius_text_y + 50;
          wxPoint* posicao_celsius_text = new wxPoint(celsius_text_x,celsius_text_y);
          wxPoint* posicao_fahrenheit_text = new wxPoint(fahrenheit_text_x,fahrenheit_text_y);
          wxSize* tamanho_texto = new wxSize(200, 25);
          celsius_text = new wxTextCtrl(janela, -1, "", *posicao_celsius_text, *tamanho_texto);
          fahrenheit_text = new wxTextCtrl(janela, -1, "", *posicao_fahrenheit_text, *tamanho_texto);
          *celsius_text << "Valor em graus Celsius";
          *fahrenheit_text << "Valor em graus Fahrenheit";
          //Inicializa os botoes
          wxSize* tamanho_botoes = new wxSize(200, 25);
          wxPoint* posicao_celsius_button = new wxPoint(celsius_text_x + tamanho_texto->GetWidth(),celsius_text_y);
          wxPoint* posicao_fahrenheit_button = new wxPoint(fahrenheit_text_x + tamanho_texto->GetWidth(),fahrenheit_text_y);
          wxButton* celsius_button = new wxButton(janela, CELSIUS_BUTTON_ID, "", *posicao_celsius_button, *tamanho_botoes);
          wxButton* fahrenheit_button = new wxButton(janela, FAHRENHEIT_BUTTON_ID, "", *posicao_fahrenheit_button, *tamanho_botoes);
          celsius_button->SetLabel("Converter Celsius para Fahrenheit");
          fahrenheit_button->SetLabel("Converter Fahrenheit para Celsius");
          janela->Show(true);
          return true;
        }
        //Tratadores de eventos
        void OnCelsiusClick(wxCommandEvent& event) {
          string s(celsius_text->GetValue());
          int i = stringToInteger(s);
          exit(0);
        }
        void OnFahrenheitClick(wxCommandEvent& event) {
          exit(0);
        }
        //Instrucao necessaria para que esta classe possa tratar eventos
        DECLARE_EVENT_TABLE()
    };
    
    //Eventos da classe CelsiusFahrenheit
    BEGIN_EVENT_TABLE(CelsiusFahrenheit, wxApp)
     EVT_BUTTON(CELSIUS_BUTTON_ID, CelsiusFahrenheit::OnCelsiusClick)
     EVT_BUTTON(FAHRENHEIT_BUTTON_ID, CelsiusFahrenheit::OnFahrenheitClick)
    END_EVENT_TABLE()
    //Iniciar a aplicacao
    IMPLEMENT_APP(CelsiusFahrenheit)
    Utilitarios.h

    Code:
    #ifndef _UTILITARIOS_H_
    #define _UTILITARIOS_H_
    class Utilitarios {
      public:
        int stringToInteger(string& s);
    };
    #endif
    Utilitarios.cpp

    Code:
    #include "Utilitarios.h"
    #include <sstream>
    #include <string>
    using namespace std;
    
    int Utilitarios::stringToInteger(string& s) {
      stringstream temp;
      temp << s;
      int i = 0;
      if (temp >> i) {
        return i;
      }
      else {
        throw "Number format exception!";
      }
    }
    And the problem is the following compilation error:

    Line 5 - Utilitarios.h - expected `;' before '(' token

    What exactly am I doing wrong? Thank you in advance.
    Name: Miguel Martins
    Date of birth: 14th August 1987

    "He who hesitates is lost."

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    You need to #include <string> inside Utilitarios.h and refer to it as std::string.

    BTW, Utilitarios can be a namespace rather than a class, if you are just going to be adding utility functions to it. If you keep it as a class, you can make stringToInteger a static function.

  3. #3
    Registered User
    Join Date
    Nov 2006
    Location
    Coimbra, Portugal
    Posts
    64
    But of course! How could I be so blind?

    Code:
    #include <string>
    using namespace std;
    
    #ifndef _UTILITARIOS_H_
    #define _UTILITARIOS_H_
    class Utilitarios {
      public:
        static int stringToInteger(string& s);
    };
    #endif
    This seems to work. Alternatively, I could use

    Code:
    #include <string>
    
    #ifndef _UTILITARIOS_H_
    #define _UTILITARIOS_H_
    class Utilitarios {
      public:
        static int stringToInteger(std::string& s);
    };
    #endif
    Thank you very much.
    Name: Miguel Martins
    Date of birth: 14th August 1987

    "He who hesitates is lost."

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Your welcome. It really doesn't matter much, but I believe general practice is to put the #include inside the header guards.

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    It is. And the alternative way is better. Never put using statements or declarations on the global level in a header file: it might surprise people that include the file.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    Registered User
    Join Date
    Nov 2006
    Location
    Coimbra, Portugal
    Posts
    64
    Quote Originally Posted by CornedBee View Post
    It is. And the alternative way is better. Never put using statements or declarations on the global level in a header file: it might surprise people that include the file.
    Understood.

    Well, I've finished my application. For those who are curious, I developed it using wxDev-C++. I built it entirely from scratch (i. e. didn't use my IDE's graphical designer). You may download it here:

    http://www.megaupload.com/?d=NQ31MIUY

    A Windows binary exists on the /Output/MingW directory. Oh, and by the way, it's in Portuguese Sorry, fellows.
    Name: Miguel Martins
    Date of birth: 14th August 1987

    "He who hesitates is lost."

  7. #7
    The larch
    Join Date
    May 2006
    Posts
    3,573
    wxWidgets has a wxString class. You are using it in at least one place - for titulo. It has a ToLong method that might do the string to integer conversion.

    By the way, it seems that you are using the new keyword way too much. All the wxPoints, wxSizes and wxStrings should be plain static objects or at least deleted after you have done with them. It's different for windows and window controls (and some other things) where the parent will take reponsibility for the new-ed objects.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  8. #8
    Registered User
    Join Date
    Nov 2006
    Location
    Coimbra, Portugal
    Posts
    64
    Quote Originally Posted by anon View Post
    wxWidgets has a wxString class. You are using it in at least one place - for titulo. It has a ToLong method that might do the string to integer conversion.

    By the way, it seems that you are using the new keyword way too much. All the wxPoints, wxSizes and wxStrings should be plain static objects or at least deleted after you have done with them. It's different for windows and window controls (and some other things) where the parent will take reponsibility for the new-ed objects.
    So you mean I should do it like this? (seems to work as well; fewer "new" keywords; OnExit method calling delete on the required pointers)

    Code:
    #define CELSIUS_BUTTON_ID 1
    #define FAHRENHEIT_BUTTON_ID 2
    #include "wx/wx.h"
    
    class CelsiusFahrenheit: public wxApp {
      public:
        //Variaveis globais
        wxTextCtrl* celsius_text;
        wxTextCtrl* fahrenheit_text;
        wxTextCtrl* output_text;
        //Metodo OnInit, iniciador da aplicacao
        bool OnInit() {
          //Inicializa a janela
          int comprimento_janela = 400;
          int largura_janela = 300;
          wxSize tamanho_janela(comprimento_janela,largura_janela);
          wxString titulo("Conversor Celsius-Fahrenheit-Celsius");
          //Janela com:
          //-CAPTION (barra de titulo)
          //-CLOSE BOX (botao fechar no canto superior direito)
          //-SYSTEM MENU (conjunto de botoes minimizar, maximizar, fechar)
          /*
          NOTA: Apenas os botoes do SYSTEM MENU que forem especificados
          (neste caso, apenas a CLOSE BOX foi especificada) aparecem na barra
          superior.
          */
          long estilo_janela = wxCAPTION | wxCLOSE_BOX | wxSYSTEM_MENU;
          wxFrame* janela = new wxFrame(NULL, -1, titulo, wxDefaultPosition, tamanho_janela, estilo_janela);
          wxColour cor_de_fundo(48, 214, 100);
          janela->SetBackgroundColour(cor_de_fundo);
          //Inicializa os controlos de texto
          int celsius_text_x = 0;
          int celsius_text_y = 0;
          int fahrenheit_text_x = celsius_text_x;
          int fahrenheit_text_y = celsius_text_y + 50;
          int output_text_x = celsius_text_x;
          int output_text_y = fahrenheit_text_y + 50;
    
          wxPoint posicao_celsius_text(celsius_text_x,celsius_text_y);
          wxPoint posicao_fahrenheit_text(fahrenheit_text_x,fahrenheit_text_y);
          wxPoint posicao_output_text(output_text_x,output_text_y);
    
          wxSize tamanho_output(400,largura_janela-output_text_y);
          wxSize tamanho_texto(200, 25);
    
          celsius_text = new wxTextCtrl(janela, -1, "", posicao_celsius_text, tamanho_texto);
          fahrenheit_text = new wxTextCtrl(janela, -1, "", posicao_fahrenheit_text, tamanho_texto);
          output_text = new wxTextCtrl(janela, -1, "", posicao_output_text, tamanho_output, wxTE_READONLY);
    
          *celsius_text << "Valor em graus Celsius";
          *fahrenheit_text << "Valor em graus Fahrenheit";
          *output_text << "Aparecera aqui o resultado de uma das conversoes.";
          //Inicializa os botoes
          wxSize tamanho_botoes(200, 25);
    
          wxPoint posicao_celsius_button(celsius_text_x + tamanho_texto.GetWidth(),celsius_text_y);
          wxPoint posicao_fahrenheit_button(fahrenheit_text_x + tamanho_texto.GetWidth(),fahrenheit_text_y);
    
          wxButton* celsius_button = new wxButton(janela, CELSIUS_BUTTON_ID, "", posicao_celsius_button, tamanho_botoes);
          wxButton* fahrenheit_button = new wxButton(janela, FAHRENHEIT_BUTTON_ID, "", posicao_fahrenheit_button, tamanho_botoes);
    
          celsius_button->SetLabel("Converter Celsius para Fahrenheit");
          fahrenheit_button->SetLabel("Converter Fahrenheit para Celsius");
    
          janela->Show(true);
          return true;
        }
        //Metodo OnExit, terminador da aplicacao
        int OnExit() {
          delete celsius_text;
          delete fahrenheit_text;
          delete output_text;
          return 0;
        }
        //Tratadores de eventos
        void OnCelsiusClick(wxCommandEvent& event) {
          wxString s = celsius_text->GetValue();
          double d = 0.0;
          if (!s.ToDouble(&d)) {
            wxMessageDialog exception_dialog(NULL,"Nao foi introduzido um valor decimal!","Erro!");
            exception_dialog.ShowModal();
            return;
          }
          double resultado = d/5.0*9.0+32; //Formula para converter um valor de Celsius para Fahrenheit
          output_text->SetValue("");
          *output_text << d << " graus Celsius correspondem a " << resultado << " graus Fahrenheit.";
        }
        void OnFahrenheitClick(wxCommandEvent& event) {
          wxString s = fahrenheit_text->GetValue();
          double d = 0.0;
          if (!s.ToDouble(&d)) {
            wxMessageDialog exception_dialog(NULL,"Nao foi introduzido um valor decimal!","Erro!");
            exception_dialog.ShowModal();
            return;
          }
          double resultado = (d-32)/9.0*5.0; //Formula para converter um valor de Fahrenheit para Celsius
          output_text->SetValue("");
          *output_text << d << " graus Fahrenheit correspondem a " << resultado << " graus Celsius.";
        }
        //Instrucao necessaria para que esta classe possa tratar eventos
        DECLARE_EVENT_TABLE()
    };
    
    //Eventos da classe CelsiusFahrenheit
    BEGIN_EVENT_TABLE(CelsiusFahrenheit, wxApp)
     EVT_BUTTON(CELSIUS_BUTTON_ID, CelsiusFahrenheit::OnCelsiusClick)
     EVT_BUTTON(FAHRENHEIT_BUTTON_ID, CelsiusFahrenheit::OnFahrenheitClick)
    END_EVENT_TABLE()
    //Iniciar a aplicacao
    IMPLEMENT_APP(CelsiusFahrenheit)
    Last edited by Mr_Miguel; 06-06-2007 at 12:15 PM. Reason: Forgot to remove unnecessary includes from my code.
    Name: Miguel Martins
    Date of birth: 14th August 1987

    "He who hesitates is lost."

  9. #9
    The larch
    Join Date
    May 2006
    Posts
    3,573
    More like that. Except I'm not very sure if you should be deleting the text controls. I guess the parent window should do that.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problems passing a file pointer to functions
    By smitchell in forum C Programming
    Replies: 4
    Last Post: 09-30-2008, 02:29 PM
  2. Encryption program
    By zeiffelz in forum C Programming
    Replies: 1
    Last Post: 06-15-2005, 03:39 AM
  3. archive format
    By Nor in forum A Brief History of Cprogramming.com
    Replies: 0
    Last Post: 08-05-2003, 07:01 PM
  4. Making a LIB file from a DEF file for a DLL
    By JMPACS in forum C++ Programming
    Replies: 0
    Last Post: 08-02-2003, 08:19 PM
  5. Hmm....help me take a look at this: File Encryptor
    By heljy in forum C Programming
    Replies: 3
    Last Post: 03-23-2002, 10:57 AM