The method is tricky as the strtok() function has side effects on a global hidden state variable. This may affect surrounding code and prove hard to debug.
Furthermore, there is a simple case where strtok(line, "\n") will not overwrite the '\n' with a null byte: If the line read by fgets() is an empty line containing only a single new line byte. For this contents, strtok() will skip the initial new line, searching for a different character, which is not present, and return NULL not modifying the array. Hence it will not strip the new line.
This is a compelling reason to not use strtok(line, "\n") to strip the new line byte.
Of course one can fix this issue by writing:
if (*line == '\n')
*line = '\0';
else
strtok(line, "\n");
Or cumbersome one-liners:
(void)(*line == '\n' ? (*line = '\0') : (strtok(line, "\n"), 0);
if (!strtok(line, "\n")) *line = '\0';
(void)(strtok(line, "\n") || (*line = '\0'));
But the code is no longer compact and still has other side effects.
Other methods are available:
using an explicit for statement:
for (char *p = line; *p; p++) {
if (*p == '\n')
*p = '\0';
}
using strlen():
size_t len = strlen(line);
if (len > 1 && line[len - 1] == '\n') {
line[--len] = '\0';
}
// len is the length if the stripped line
using strchr():
char *p = strchr(line, '\n');
if (p) {
*p = '\0';
}
using strcspn() in a one-liner:
line[strcspn(line, "\n")] = '\0'; // strip the newline if any.