Let's write a program that counts the number of numbers, whitespace characters (including spaces, tabs, and line breaks) and the occurrences of all other characters. The utility of this program is not very practical, but we can use the program to discuss various aspects of C language.
All the input characters can be divided into 12 classes, so you can use an array to hold the number of occurrences of each number, which is more convenient than using 10 independent variables. The following is a version of the program:
#include <stdio.h>
/* count digits, white spaces, others
/main ()
{
int c, I, Nwhite, nother;
int ndigit[10];
Nwhite = nother = 0;
for (i = 0; i < ++i)
ndigit[i] = 0;
while ((c = GetChar ())!= EOF)
if (c >= ' 0 ' && C <= ' 9 ')
++ndigit[c-' 0 '];
else if (c = = ' | | c = = ' \ n ' | | c = = ' t ')
++nwhite;
else
++nother;
printf ("digits =");
for (i = 0; i < ++i)
printf ("%d", Ndigit[i]);
printf (", white spaces =%d, other =%d\n", Nwhite, nother);
}
When the program itself as input, the output is: digits = 9 3 0 0 0 0 0 0 0 1, white spaces = 123, other = 345
The declaration statement int NDIGIT[10] in the program declares the variable ndigit as an array of 10 integer numbers. In C, the array subscript always starts at 0, so the 10 elements of the array are ndigit[0], ndiglt[1] 、...、 ndigit[9], which can be reflected by initializing and printing the two for loop statements for the array.
An array subscript can be any integer expression, including an integer variable (such as I) and an integer constant.
The execution of the program depends on the character representation property of the number. For example, the test statement if (c >= ' 0 ' && C <= ' 9 ') is used to determine whether the character in C is a number. If it is a number, then the number corresponds to the value of C ' 0 '. This is only possible if the ' 0 ', ' 1 ' 、...、 ' 9 ' have continuously incremented values. Luckily, all of the character sets are like this.
As defined by the definition, char-type characters are small integers, so variables and constants of the char type are equivalent to variables and constants of type int in an arithmetic expression. This is both natural and convenient, for example, C-' 0 ' is an integer expression, and if the character stored in C is ' 0 ' ~ ' 9 ', its value will be 0~9, so it can act as a legitimate subscript for the array ndigit.
The ability to determine whether a character is a number, whitespace, or other character can be completed by the following sequence of statements:
if (c >= ' 0 ' && C <= ' 9 ')
++ndigit[c-' 0 '];
else if (c = = ' | | c = = ' \ n ' | | c = = ' t ')
++nwhite;
else
++nother;
Multiple-path judgments are often represented in programs in the following ways:
if (condition 1)
Statement 1
else if (condition 1)
Statement 2
...
...
Else
Statement n
In this way, each condition is evaluated sequentially from the point of departure until a condition is met, and then the corresponding statement part is executed. After this part of the statement is completed, the entire statement body is executed (any of these statements can be several statements enclosed in curly braces). If all the conditions are not satisfied, execute the statement (if any) after the last else. Similar to the previous word-counting program, if there is no last else and the corresponding statement, the statement body will not perform any action. There can be 0 or more of the following statement sequences between the first if and the last else:
else if (condition)
Statement
As far as the programming style is concerned, we recommend that the reader adopt the indented format shown above to reflect the hierarchical relationship of the structure, otherwise, if each if is indented some distance from the previous else, the longer decision sequence may go beyond the right edge of the page.
Character array
a character array is the most commonly used array type in C language. Here we write a program to illustrate the use of character arrays and functions that manipulate character arrays. The program reads a set of lines of text and prints the longest lines of text. The basic framework of the algorithm is very simple:
While (there are still rows that are not processed)
If (the row is longer than the longest line that has been processed)
Save the longest line of the behavior
Save the length of the line
Print the longest line
It is easy to see from the framework above that the program is naturally divided into fragments, used to read new rows, to test the read rows, to save the row, and the remainder to control the process.
Because this method of partitioning is reasonable, you can write programs in this way. First, we write a separate function getline, which reads the next line of input. We try to keep the function on the other field table also useful. At least the Getline function should return a signal when it is read to the end of the file; a more useful design is that it can return the length of the row when the text line is read, and return 0 when the end of the file is encountered characters. Because 0 is not a valid length, it can be a return value that ends with a flag file. Each line consists of at least one character, containing only the line of the newline character, with a length of 1.
When you find that a newly read row is longer than the longest line you read before, you need to save the row. In other words, we need to copy the new line to a secure location with another function copy.
Finally, we need to control both the Getline and copy functions in main function main. Here is the procedure we have written:
#include <stdio.h> #define MAXLINE 1000/* Maximum input line length */int getline (char line[], int maxline);
void copy (char to[], char from[]);
/* Print the longest input line */main () {int len;
int Max; /* Current LINE length * * * Maximum length seen so far/char line[maxline]; /* Current input line */char longest[maxline];
/* Longest line saved here * * max = 0;
while (len = Getline (line, Maxline) > 0) if (len > Max) {max = Len;
Copy (longest, line);
if (Max > 0)/* There is a line */printf ("%s", longest);
return 0;
}/* Getline:read a line to S, return length */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;
++i;
} S[i] = ';
return i; }/* copy:copy ' from ' in ' to ';
Assume to be big enough/void copy (char to[], char from[]) {int i;
i = 0;
while ((to[i] = from[i]) ++i!= ';
} </stdio.h>
The beginning of the program declares both Getline and copy functions, assuming that they are all stored in the same file.
Data is exchanged between main and getline through a pair of parameters and a return value. In the Getline function, two parameters are passed through the program line.
int getline (char s[], int lim)
Declared, it declares the first argument s as an array, and the second parameter, Lim, as an integral type, and the purpose of providing the array size in the declaration is to set aside storage space. It is not necessary in the Getline function to indicate the length of the array s because the size of the array is set in the main function. Like the power function, the Getline function uses a return statement that returns a value to its caller. The above program line also declares that the return value type of the getline number is int. Because the default return value type of the function is int, the int here can be omitted.
Some functions return useful values, and some functions (such as copy) are used only to perform some actions and do not return a value. The return value type of the copy function is void, which explicitly shows that the function does not return any values.
The Getline function inserts the character ' "(that is, the null character, whose value is 0) into the end of the array it creates to mark the end of the string. This Convention has been adopted in C language: When the C language program appears similar to
string constant, it will be stored as an array of characters, each of which stores each character of the string and ends with the ' I ' flag string.
The format specification%s in the printf function stipulates that the corresponding argument must be a string in this form. The implementation of the copy function relies on the fact that the input parameter is terminated by ' the ', which copies ' the ' to the output parameter. In other words, the empty character ' "is not part of the normal text.
It is worth mentioning that even the above such a small program, in passing parameters will also encounter some problems in the design problem. For example, when the length of the read is greater than the maximum allowable value, the main function should be handled, and the execution of the Getline function is safe, regardless of whether or not the newline character is reached, and it stops reading characters when the array is full. The main function can determine whether the current row is too long by testing the length of the row and checking the last character returned, and then handling it according to the specific situation. In order to simplify the procedure, we do not consider this issue here.
A program that calls the Getline function cannot know the length of the input line in advance, so the Getline function needs to check for overflow. On the other hand, the program that calls the copy function knows (and can find) the length of the string, so the function does not need to be checked for errors.