Nice layout/formatting
Object names are reasonable.
Saving more than about 80 characters is not needed
Once the "80" line length is reach, print the first 80 characters and then the rest of incoming characters until end-of-line/end-of-file.
char minCharsLine[MAXLINE][MAXLINE]
, int lineCharCount[MAXLINE]
not needed.
Good that code saved the return value of getchar()
in an int
getchar()
returns 257 different values*1. Saving in a char
can lose information.
Function signature
For this student exercise, int getLine(char line[], int size);
is OK - but curiously never defined?
In C, array indexes can exceed INT_MAX
. The unsigned type size_t
is size to accommodate all array indexing and object sizing. Consider
size_t getLine(char line[], size_t size);
// or
size_t getLine(size_t size, char line[]);
The first form is more common.
Advanced: The 2nd has an advantage when coded as
size_t getLine(size_t size, char line[size]);
Yet for various portability concerns, this needs to wait until C2x.
Must the last line contain a '\n'
?
Your design choice.
Best to be clear about what code does if it received an EOF
following a non-'\n'
. That is, the last line did not end with a '\n'
.
A text stream is an ordered sequence of characters composed into lines, each line consisting of zero or more characters plus a terminating new-line character. Whether the last line requires a terminating new-line character is implementation-defined. C17dr § 7.21.2 2
MAXLINE
is not necessarily the same as LINECOUNT_N
Better as:
// char minCharsLine[MAXLINE][MAXLINE];
#define LINECOUNT_N 1024
char minCharsLine[LINECOUNT_N][MAXLINE];
MAXLINE
versus alternates
Many off-by-one errors stem from not being clear.
MAXLINE
sounds like the maximum returned strlen(line)
. To achieve that length, the array size needed is MAXLINE + 1
.
Perhaps:
#define MAXLINE 80
#define LINE_SIZE (MAXLINE + 1)
char line[LINE_SIZE];
// or
#define MAXLINE 80
char line[MAXLINE + 1];
Line counts can be large
Code performs minCharsLine[lineCount]
without ever checking if lineCount
is too high. Better to exit with an error message than go on.
The line count of a file is not limited to INT_MAX
. I'd use unsigned long
or uintmax_t
for the line count. Of course even that is not the upper bound, just a safer bet.
Simplification
OP's code is OK and does handle the unexpected reading of null characters and "prints" them with:
for (int j = 0; j < lineCharCount[i]; j++) {
printf("%c", minCharsLine[i][j]);
}
Simplier to use:
fwrite(minCharsLine[i], lineCharCount[i], 1, stdout);
If code does not need to support reading null characters, make sure minCharsLine[i]
is 1 wider, append a null character to minCharsLine[i]
,and use the below:
fputs(minCharsLine[i], stdout);
Simplify??
Along time ago printf("%c", minCharsLine[i][j])
was considered inefficient versus the simpler putchar(minCharsLine[i][j])
. That still applies to some compilers today, yet good compilers are smart and will emit efficient code either way.
Using putchar(minCharsLine[i][j])
is typically better, yet for such linear optimization cases as this over that, do consider clarity of code and let the compiler cope with optimizations.
fgets()
fgets()
is mostly a drop in replacement for this exercise, yet it has functional difference in special cases.
*1 EOF
and [0...UCHAR_MAX
]. This may be more than 257 different values when UCHAR_MAX
is more than 255.
'\n'
? \$\endgroup\$