How to use header files (.h and .cpp) in an online C++ compiler

A one-file online compiler has nowhere to put Student.h, so #include "Student.h" stops with "No such file or directory". OnlineCompiler.io's API takes Student.h and Student.cpp beside your main program, compiles every .cpp file you send and links them into one program, as g++ does on your own computer. If your course has you #include "Student.cpp" instead, that works too.

By the OnlineCompiler.io team. Updated .

Why does #include "Student.h" fail in an online compiler?

#include "Student.h" tells the compiler to read the file Student.h from the folder of the file that includes it. A one-file online compiler saves your code as a single file in an empty folder, so the header is not there. This is what g++ prints when the main.cpp below runs with no other files (your program is saved as code.cc, so messages name that file):

Error (exit code 1)
code.cc:2:10: fatal error: Student.h: No such file or directory
    2 | #include "Student.h"
      |          ^~~~~~~~~~~
compilation terminated.

The header alone is not enough either. It only declares the class; the member functions are written in Student.cpp, and without that file the linker stops with undefined reference (see the errors below). The program needs both files, compiled together.

Our own C++ online compiler page is one file too: its editor has no way to add a second file. There you can paste the class into the same file above main, which works in any online compiler. To keep the files separate, send them to the API, as the next section shows.

How do I run Student.h and Student.cpp with my main program?

Here is a small class split the usual way, with the declaration in the header and the code in the .cpp file:

Student.h
#ifndef STUDENT_H
#define STUDENT_H

#include <string>

class Student {
public:
    Student(const std::string& name, int score);
    std::string name() const;
    bool passed() const;

private:
    std::string name_;
    int score_;
};

#endif
Student.cpp
#include "Student.h"

Student::Student(const std::string& name, int score) : name_(name), score_(score) {}

std::string Student::name() const { return name_; }

bool Student::passed() const { return score_ >= 50; }
main.cpp
#include <iostream>
#include "Student.h"

int main() {
    Student ada("Ada", 91);
    Student tim("Tim", 42);
    std::cout << ada.name() << (ada.passed() ? " passed" : " failed") << "\n";
    std::cout << tim.name() << (tim.passed() ? " passed" : " failed") << "\n";
}

To run it:

  1. Get a free API key (100,000 runs a month, no credit card).
  2. Put main.cpp in the request's code: it is the program, and holds main.
  3. Put the other files in files, each as a name and its content. The name must match your #include exactly, capital letters included.
  4. Send it to https://api.onlinecompiler.io/api/run-code-sync/ with the compiler g++-15 (GNU C++17), or g++-15-cpp20 for C++20.
Terminal
curl -X POST https://api.onlinecompiler.io/api/run-code-sync/ \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "compiler": "g++-15",
    "code": "#include <iostream>\n#include \"Student.h\"\n\nint main() {\n    Student ada(\"Ada\", 91);\n    Student tim(\"Tim\", 42);\n    std::cout << ada.name() << (ada.passed() ? \" passed\" : \" failed\") << \"\\n\";\n    std::cout << tim.name() << (tim.passed() ? \" passed\" : \" failed\") << \"\\n\";\n}\n",
    "files": [
      {
        "name": "Student.h",
        "content": "#ifndef STUDENT_H\n#define STUDENT_H\n\n#include <string>\n\nclass Student {\npublic:\n    Student(const std::string& name, int score);\n    std::string name() const;\n    bool passed() const;\n\nprivate:\n    std::string name_;\n    int score_;\n};\n\n#endif\n"
      },
      {
        "name": "Student.cpp",
        "content": "#include \"Student.h\"\n\nStudent::Student(const std::string& name, int score) : name_(name), score_(score) {}\n\nstd::string Student::name() const { return name_; }\n\nbool Student::passed() const { return score_ >= 50; }\n"
      }
    ]
  }'

The response's output is what the program printed, and exit_code is 0:

Output
Ada passed
Tim failed

The server compiles your program with every .cc, .cpp and .cxx file you send and links them into one program, here g++ -O2 -Wall code.cc Student.cpp -o code.out. Headers are not compiled on their own; they are read where a file includes them. Add "input" to the request when the program reads from cin.

Can I #include "Student.cpp" instead of the header?

Yes. Some courses have main.cpp include the .cpp file, so the class arrives with its code in one step. Send the same two files and change the include:

main.cpp
#include <iostream>
#include "Student.cpp"

int main() {
    Student ada("Ada", 91);
    Student tim("Tim", 42);
    std::cout << ada.name() << (ada.passed() ? " passed" : " failed") << "\n";
    std::cout << tim.name() << (tim.passed() ? " passed" : " failed") << "\n";
}
Terminal
curl -X POST https://api.onlinecompiler.io/api/run-code-sync/ \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "compiler": "g++-15",
    "code": "#include <iostream>\n#include \"Student.cpp\"\n\nint main() {\n    Student ada(\"Ada\", 91);\n    Student tim(\"Tim\", 42);\n    std::cout << ada.name() << (ada.passed() ? \" passed\" : \" failed\") << \"\\n\";\n    std::cout << tim.name() << (tim.passed() ? \" passed\" : \" failed\") << \"\\n\";\n}\n",
    "files": [
      {
        "name": "Student.h",
        "content": "#ifndef STUDENT_H\n#define STUDENT_H\n\n#include <string>\n\nclass Student {\npublic:\n    Student(const std::string& name, int score);\n    std::string name() const;\n    bool passed() const;\n\nprivate:\n    std::string name_;\n    int score_;\n};\n\n#endif\n"
      },
      {
        "name": "Student.cpp",
        "content": "#include \"Student.h\"\n\nStudent::Student(const std::string& name, int score) : name_(name), score_(score) {}\n\nstd::string Student::name() const { return name_; }\n\nbool Student::passed() const { return score_ >= 50; }\n"
      }
    ]
  }'
Output
Ada passed
Tim failed

Both styles work because of one rule: a file that the program, or another of its files, includes with #include "..." is compiled only through that include, not again on its own. In the header style nothing includes Student.cpp, so it is compiled and linked with the program. In this style the program includes it, so its code is compiled once, inside the program. Either way each function is compiled exactly once.

On your own computer the two styles need different commands. With the header, build both files: g++ main.cpp Student.cpp -o main. With #include "Student.cpp", build only g++ main.cpp -o main. Building both in that style compiles the class twice, and the linker refuses it (g++ 15, shortened):

Terminal
$ g++ main.cpp Student.cpp -o main
/usr/bin/ld: /tmp/cciho97q.o: in function `Student::Student(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)':
Student.cpp:(.text+0x0): multiple definition of `Student::Student(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)'; /tmp/ccteijRb.o:main.cpp:(.text+0xb0): first defined here
...
collect2: error: ld returned 1 exit status

An IDE or online editor that builds every .cpp file in a project does the same, so there include the header. Headers are also how larger C++ programs are built, so use them when your course lets you.

How do I send my files from Python?

This script reads main.cpp and the files you list from the folder it runs in, sends them and prints the result. It needs the requests package (pip install requests).

run.py
# run.py: runs main.cpp with its header and source files. Run it in the folder that holds them.
from pathlib import Path

import requests

# Every other file the program needs. Folders work too, such as "lib/Point.h".
files = ["Student.h", "Student.cpp"]

response = requests.post(
    "https://api.onlinecompiler.io/api/run-code-sync/",
    headers={"Authorization": "YOUR_API_KEY"},
    json={
        "compiler": "g++-15",
        "code": Path("main.cpp").read_text(),
        "files": [{"name": name, "content": Path(name).read_text()} for name in files],
    },
    timeout=60,
)
if not response.ok:
    raise SystemExit(f"HTTP {response.status_code}: {response.text}")
result = response.json()
print(result["output"], end="")
print(result["error"], end="")
print("exit code:", result["exit_code"])
python run.py
Ada passed
Tim failed
exit code: 0

The official Python and Node.js clients take the same files list in their run method. The several source files docs list the rules for every language.

What do these C++ errors mean?

Each of these was printed by a run on the service:

ErrorWhat it meansFix
fatal error: Student.h: No such file or directoryThe header was not sent, or its name differs from the #include. Names are case-sensitive: student.h is not Student.h.Send it in files under the exact name the program includes.
undefined reference to `Student::Student(...)'The header was found, but no file defines the functions it declares.Send Student.cpp too, named .cpp, .cc or .cxx.
redefinition of 'class Student'One file read the header twice (here main.cpp included Student.h and Student.cpp, which includes it again), and the header has no include guard.Wrap the header in #ifndef STUDENT_H, #define STUDENT_H and #endif, or start it with #pragma once.
multiple definition of `passMark()'A function's body is written in a header that two .cpp files include, so it is compiled twice.Move the body into the .cpp file and keep the declaration in the header, or mark the function inline.
multiple definition of `main'A second file, often a .cpp with a test main left in, defines main too.Keep main in the program only.

The full undefined reference message names every missing function (shortened here):

Error (exit code 1)
/usr/bin/ld: /tmp/ccdg4WQe.o: in function `main':
code.cc:(.text.startup+0x33): undefined reference to `Student::Student(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)'
...
collect2: error: ld returned 1 exit status

Which online C++ compilers support several files?

If you want to write and click Run in a browser with a tab per file, an online IDE with projects fits better than an API. This is how some online C++ tools handle several files:

ToolSeveral filesWhat it does well
OnlineGDBYes: add or upload files to a project in the editor (its Q&A). In one user's thread, including a source file that the project also built gave "multiple definition", and the advice was to include the header.A debugger in the browser: step through the program line by line.
PlaycodeYes: .cpp and .h files in folders (its C++ page).Compiles in your browser, with Clang built as WebAssembly, and supports C++20.
ReplitYes, according to University of Regina lab notes: Run compiles every C++ file in the project into one program. Check Replit's current plans and limits yourself.A full project in the browser, with files and folders you manage yourself.
One-file online compilers, including our C++ pageNo: paste the class into the file above main.Quick runs with nothing to set up.
OnlineCompiler.io APIYes: up to 20 files in files, folders allowed; both the header and the #include "Student.cpp" style work.Running the files from a script, a course platform or an autograder, in 46 languages. No multi-file editor in the browser.

Can I grade a student's Student.cpp automatically?

Yes. The same files list works with run-tests, which runs the program against inputs and expected outputs and marks each test passed or failed, so the student's class and the main you test it with travel in one request. With a stored problem, a grader file such as grader.cpp can hold main and call the functions the student writes. The autograder API page covers grading a whole class.

Frequently asked questions

Can I put the files in folders?

Yes. A file name may hold folders, such as lib/Student.h, up to 4 parts and 200 characters. An #include is found from the folder of the file that holds it: main includes "lib/Student.h", and lib/Student.cpp includes "Student.h". A .cpp file in a folder is compiled and linked like one at the top.

How many files can I send with one run?

Up to 20 files and 1 MB in total, besides the program itself, which can be up to 100 KB. A run with files costs the same as any run, and the Free plan has 100,000 runs a month.

Does it work for C?

Yes. Use the compiler gcc-15 and send your .h and .c files the same way: every other .c file is compiled and linked with the program, except a file that another file includes with #include, which is compiled only through that include.

What about Java?

Yes. Send Student.java beside the program, which holds main, and Java finds the class by its file name. A class in a package goes in its package folder, such as school/Student.java for package school.

Can I do this on the C++ online compiler page?

Not with separate files: the editor on the C++ online compiler page holds one file. Paste the class into that file above main, or send your files to the API as this guide shows.