Reading and classifying lines from a file
Code has bug. After free'ing line, set len = 0; line = NULL;

    free(line);
    line = NULL; // add
    len = 0; // add


Further, it would be better to initialize line and move this free();  ... to outside the for()   loop.  Also line = NULL; len = 0; would not be needed there.

size_t len = 0;
char *line = NULL;
...
for(...; ... getline(&amp;line, &amp;len, file) ...; ...) {
  ...
}
free(line);





  Is this way of writing the if statement a good practice? Is it readable? Should I do it differently?


It is not clear that the  { printError(... true; } block is part of if() and not a free standing block.  Consider the below.  The first lacks clarity that the first block is part of the if() and the 2nd block simply a stand-along block

    if (strToSample(line, SEPARATOR, dim, sample) != EXIT_SUCCESS ||
        calibrateLinearSeparator(sample, linearSeparator, dim) != EXIT_SUCCESS)
    {
        printError(TRAINING, "Failed processing line");
        stop = true;
    }
    {
        printError(TRAINING, "Status");
    }
    free(line);
    freeSample(sample);


vs. this form.  The 1st block is part of the if() and the 2nd block is not nested like the first.

    if (strToSample(line, SEPARATOR, dim, sample) != EXIT_SUCCESS ||
        calibrateLinearSeparator(sample, linearSeparator, dim) != EXIT_SUCCESS)
      {
        printError(TRAINING, "Failed processing line");
        stop = true;
      }
    {
        printError(TRAINING, "Status");
    }
    free(line);
    freeSample(sample);





  Is it a good practice in C to write the for condition the way I did? 


Why read a line if stop is true?  Certainly this is surprising functionality.  Given 3 stopping conditions, it appears to me that the combination of them occurring in groups, the side effects of getline() , and the short-circuit nature of &amp;&amp; led to weak function flow.

for(int i = 0; i &lt; m &amp;&amp; getline(&amp;line, &amp;len, file) != -1 &amp;&amp; !stop; i++)
// vs. 
for(int i = 0; i &lt; m &amp;&amp; !stop &amp;&amp; getline(&amp;line, &amp;len, file) != -1; i++)


IMO, a for() loop is best as for (initialize_index, index_test; index_delta).  Another other stopping condition belongs in the body.  Example:

for (int i = 0; i &lt; m; i++) {
  if (stop || getline(&amp;line, &amp;len, file) == -1) {
    break;
  }
  ...
}


Notice this form avoid ! in 2 places.  Negation adds to complexity.  Don't you not think it is not so and not so when not done?