krx51301.c
来自「answer of the c programming language sec」· C语言 代码 · 共 134 行
C
134 行
/* K&R Exercise 5-13 */
/* Steven Huang */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEFAULT_NUM_LINES 10
#define MAX_LINE_LEN 1000
/*
Points of interest for a novice:
1. atoi() has a normally annoying property of not being able to
tell the caller conclusively whether the input was bad ("abc")
or it was really zero ("0"), because it returns 0 for both
cases. Here, we exploit that property, because we only want
to accept options in the form of "-n".
2. Try to understand how this program deals with input that
doesn't even have as many lines as the line_ptrs[] array.
That is, how does this program degenerate into just displaying
everything it read? (Hint: what does it mean when line_ptrs[x]
is NULL?)
3. Using modulo arithmetic on an index to a circular array is
a common and useful technique. Try to understand the range
of values that current_line (and j, later) will take. In
particular, why shouldn't we just do this:
for (i = 0; i < num_lines; i++)
if (line_ptrs[i])
printf("%s", line_ptrs[i]);
4. Why do we still use a "%s" to display what's inside line_ptrs,
rather than just:
printf(line_ptrs[i]);
5. There is a bug in this program, where you see:
numlines = -numlines;
When will this break?
*/
/* K&R2 p29 */
int getline(char s[], int lim)
{
int c, i;
for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; i++)
s[i] = c;
if (c == '\n')
s[i++] = c;
s[i] = '\0';
return i;
}
/* duplicates a string */
char *dupstr(const char *s)
{
char *p = malloc(strlen(s) + 1);
if (p)
strcpy(p, s);
return p;
}
int main(int argc, char *argv[])
{
int num_lines = DEFAULT_NUM_LINES;
char **line_ptrs;
char buffer[MAX_LINE_LEN];
int i;
unsigned j, current_line;
if (argc > 1) {
/*
We use a little trick here. The command line parameter should be
in the form of "-n", where n is the number of lines. We don't
check for the "-", but just pass it to atoi() anyway, and then
check if atoi() returned us a negative number.
*/
num_lines = atoi(argv[1]);
if (num_lines >= 0) {
fprintf(stderr, "Expected -n, where n is the number of lines\n");
return EXIT_FAILURE;
}
/* Now make num_lines the positive number it's supposed to be. */
num_lines = -num_lines;
}
/* First, let's get enough storage for a list of n pointers... */
line_ptrs = malloc(sizeof *line_ptrs * num_lines);
if (!line_ptrs) {
fprintf(stderr, "Out of memory. Sorry.\n");
return EXIT_FAILURE;
}
/* and make them all point to NULL */
for (i = 0; i < num_lines; i++)
line_ptrs[i] = NULL;
/* Now start reading */
current_line = 0;
do {
getline(buffer, sizeof buffer);
if (!feof(stdin)) {
if (line_ptrs[current_line]) {
/* there's already something here */
free(line_ptrs[current_line]);
}
line_ptrs[current_line] = dupstr(buffer);
if (!line_ptrs[current_line]) {
fprintf(stderr, "Out of memory. Sorry.\n");
return EXIT_FAILURE;
}
current_line = (current_line + 1) % num_lines;
}
} while (!feof(stdin));
/* Finished reading the file, so we are ready to print the lines */
for (i = 0; i < num_lines; i++) {
j = (current_line + i) % num_lines;
if (line_ptrs[j]) {
printf("%s", line_ptrs[j]);
free(line_ptrs[j]);
}
}
return EXIT_SUCCESS;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?