IX Nap Time
IX Nap Time

Reputation: 13

Organizing files in C++

I've recently started learning C++, and I've downloaded Microsoft Visual Studio to run my programs. To practice, I want to go through the Project Euler problems. As it is, I'm making a different project for each problem, which seems excessive to me.

Another option would be to have in the main file

#include "Problem[x].h"
int main(){
    solve[x]();
    return 0;
}

where I would manually replace [x] with the problem number (e.g. "Problem2.h" and "solve2"), and then have a header file (e.g. "Problem2.h") with

void solve[x]();

and the C++ file (e.g. "Problem2.cpp") would have

#include <iostream>
#include "Problem[x].h"

void solve[x](){
    //stuff
    std::cout << answer;
}

The problem with this approach is that for every problem, I'd have to make two new files (header and C++). Is there any way to avoid making so many new files? If I could have a different C++ file for each problem, and then "call" a specific one from a main file, that would be ideal.

Upvotes: 1

Views: 426

Answers (2)

sigma
sigma

Reputation: 2953

While I don't use Visual Studio, I am a C++ and Project Euler enthusiast. Although I do use the command line, I prefer compiling with the IDE (and CMake) and I do always create a new project for each problem, no matter how small. Beyond these preferences, however:

  • It's not strictly necessary to always have separate header and implementation files. The practice of putting only certain things in header files stems from C++'s compilation process and "one definition rule". But if you start writing template code, there might not be any implementation you could put in a separate file; part of the C++ standard library is header-only for this reason. It's explained in more detail in this answer. In short, writing all code for a solution in a single .h file (or .cpp!) and then including that file in main.cpp is equivalent to writing the same code at the top of main.cpp, and this will not be an issue if you're only including and compiling one such file at a time.

  • If any of this code is reusable and you wish to share it among multiple files, which is very good practice in general, then yes, it's also good practice in C++ to expose only as much as necessary in a header with "include guards", separate from its implementation. This can be just within a project, or you can separate the code into a library to share it across multiple projects.

Upvotes: 0

David C. Rankin
David C. Rankin

Reputation: 84521

While VS is a very capable IDE, one significant drawback is when you need to compile a number of simple files (even not so simple projects) and you don't want to spend the time setting up a new Project of each file you need to compile. The Answer Is - Compile from the command line, no project, no additional setup, just invoke the VS compiler cl.exe directly with the options needed.

VS provides just such a command-line called the VS Developers Command Prompt. VS provides the VS Developers Command Prompt with a complete build configuration for the command prompt. To build file.cpp into file.exe, simply use:

cl /nologo /W3 /Ox /EHsc /Fefile.exe /Tp file.cpp

(the /Tp is optional and just tells the compiler that the next source file is a C++ file instead of a /Tc (C file).

No project, no muss no fuss.allowing you to compile from the command line outside of the VS IDE. This allows you to compile any source file you like without setting up a project or messing with anything else.

Simply create a source directory to put all your C++ sources in, say Documents\cpp (it can be any directory you want). Now just save all your source files to that directory and open the VS Developers Command Prompt and change to that directory. The VS compiler is cl.exe. You can invoke it as simple cl and to see all options you would use cl /?.

If you create a bin directory under cpp you can put all your executables in bin using the /Fe option (above the change is /Febin/file.exe. This keeps your source directory clean of executables. You can do the same for obj files. Create the obj directory and add the option /Foobj/file. Now your excutables end up under bin and your object files under obj.

You can write a short batch file to build for you (say c+.bat) where the file contains (among other checks) cl /nologo /W3 /Ox /EHsc /Foobj/%~n1 /Febin/%~n1 /Tp %~1. Now to compile your code to executable, placing the executable in bin and the object file in obj all you need is c+ file.cpp and it does the rest.

A full example batch file that does basic checking that at least one arguments is given and that the file extension is .cpp could be written as:

@echo off

if "%~1" == "" goto insuffic
if not "%~x1" == ".cpp" goto notcfile

if not exist obj mkdir obj
if not exist bin mkdir bin

echo --
echo cl /nologo /W3 /wd4996 /Ox /EHsc /Foobj/%~n1 /Febin/%~n1 /Tp %~1
echo --

cl /nologo /W3 /wd4996 /Ox /EHsc /Foobj/%~n1 /Febin/%~n1 /Tp %~1

goto done

:insuffic
echo error: insufficient input.
goto usage

:notcfile
echo error: not a c++ file.

:usage
echo usage: %~nx0 file.cpp

:done

(minimal batch file to compile a source file as described above, with a few sane checks included. Just put this batch file in your source directory cpp)

The batch file above will create the bin and obj directories for you if they don't exits.

Being able to invoke the command line compiler will save you an incredible amount of time compiling short programs (with one or more source files). You can compile and debug 10 sources in the time it takes to set up and configure a single project in VS.

Not to mention using the command line will force you to learn what compiler options and libraries are needed to compile your programs. With that knowledge, you can then easily tell VS how you want your project configured, rather than just hoping VS set the correct defaults...

You can compile simple C++ files or full windows projects from the command line. It's all a matter of knowing what options are needed and what libraries need to be included to provide whatever type windows controls you are using.

Lastly, don't forget to configure the VS Developers Command Prompt with the font and number of rows/columns you want. Just click the icons at the top-left of the title-bar and choose "Properties". 12pt font works well with roughly 60 rows and 116 columns. (and set at least 1000 lines of scroll back so you can capture and review long output or at least as many as the lines of buffer you choose).

If you can't change the settings for the VS Developers Command Prompt directly, simply create a copy of the shortcut -- then you can save the font/rows/columns and lines of scrollback between sessions.

Give it a go. I've compiled hundreds, if not thousands, of programs this way and there is no more efficient way to do it. Let me know if you have further questions.

Upvotes: 1

Related Questions