skip to Main Content

# First test **I want to succeed this way**

SCREENSHOT BELOW

In folder Source file main.c

In folder Source file controller.c

In folder Headers file controler.h

In folder .vscode file c_cpp_properties.json

In folder .vscode file launch.json

#include <stdlib.h>
#include <stdio.h>
#include "controller.h" 


int main(){

double resultat;
resultat = airRectangle(10.0,20.0);

printf("L'aire du rectangle est %f",resultat);

    return 0;
}

`Give me

fatal error No such file or directory`

`#include "controller.h"
      |          ^~~~~~~~~~~~~~`

`# Second test

It works correctly this way for small projects so please help me
`

J’ai changer le fichier controller.h dans le dossier source et changer dans le fichier main.c ( #include "controler.h" ) pour (#include "controller.c )
I change the controller.h file in the source folder and change in the main.c file ( #include "controler.h" ) to (#include "controller.c )I

I watch on stack overflow and youtube for all answer.

2

Answers


  1. You could use CMake and Ninja to handle these (relatively?) complex folder structures.
    Instead of remembering what complicated commands you have to give to the compiler and changing it every time you add a new file.

    As I see, this is your folder structure

    Application
     |
     |- Headers
     |   |
     |   |- controller.h
     |
     |- source
     |   |
     |   |- output
     |   |   |
     |   |   |- controller.exe
     |   |   |- main.exe
     |   |
     |   |- controller.c
     |   |- main.c
    

    For this, you can have a CMake file like this.

    cmake_minimum_required(VERSION 3.19)
    set(PROJECT_NAME "Application")
    project(${PROJECT_NAME} VERSION 0.1 LANGUAGES C CXX)
    
    add_executable(${PROJECT_NAME} source/main.c)
    
    target_sources(${PROJECT_NAME} PRIVATE  source/controller.c)
    target_include_directories(${PROJECT_NAME} PRIVATE Headers)
    

    This file should be saved as CMakeLists.txt in the "application" folder.

    Then in terminal, use Cmake and Ninja to build.

    cmake -G Ninja -B build
    ninja -C build
    

    This will build and place your program executable in the build folder.

    Ps, you should consider making your project structure like this:

    Application
     |
     |- controller
     |   |
     |   |- controller.h
     |   |- controller.c
     |
     |- CMakeLists.txt
     |- main.c
    
    Login or Signup to reply.
  2. Quoted from GCC documents:

    2.1 Include Syntax

    (…)
    #include "file"
    This variant is used for header files of your own program. It searches for a file named file first in the directory containing the current file, then in the quote directories and then the same directories used for <file>. You can prepend directories to the list of quote directories with the -iquote option.

    2.3 Search Path

    By default, the preprocessor looks for header files included by the quote form of the directive #include "file" first relative to the directory of the current file, and then in a preconfigured list of standard system directories. For example, if /usr/include/sys/stat.h contains #include "types.h", GCC looks for types.h first in /usr/include/sys, then in its usual search path.

    When the compiler compiles main.c during your first test, the directory of the current file is source. But the preprocessor couldn’t find controller.h under source directory, therefore it throws a "No such file or directory" error. It won’t find you the file in the Headers directory.

    This is your file structure you showed: (Edited from @Usman Mehmood’s answer)

    Application
     |- .vscode
     |- Headers
     |   |- controller.h
     |- source
     |   |- output
     |   |   |- controller.exe
     |   |   |- main.exe
     |   |- controller.c
     |   |- main.c
    

    In your second test, you moved/copied controller.h to the source directory, and changed the include file to controller.c. This time the preprocessor found controller.c and replaced #include "controller.c" to the code in the file. Then it replaced #include "controller.h" with the code in controller.h. Therefore the code compiles correctly.

    Technically speaking, the following code in your controller.h only includes the declaration of the airRectangle function, but not the definition of the function.

    double airRectangle(double largeur, double hauteur);
    

    The definition is included in controller.c :

    double airRectangle(double largeur, double hauteur){
        return largeur * hauteur;
    }
    

    The compiler would throw a "undefined reference" error if you simply move/copy controller.h to the Header directory. I suggest you to move the definition of the function to controller.h.

    To solve this problem, you can:

    1. move/copy controller.h to source directory.

    2. tell the compiler to look for controller.h in the Header directory by using the -I compile parameter. Quoted from this article:

      (…)
      The simplest is by providing the compiler flag -I. -I is followed by an absolute or relative (to the current directory) path, with no spaces, and inserts the named directory at the beginning of the "angle-bracket" search path.

      For example, you can use -Ifoldername to tell the compiler to find for header file in the foldername directory. To let the compiler find controller.h, you can add -IHeaders to the compile arguments(-I C:/Users/fredd/OneDrive/Bureau/Application/Headers for full path).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search