Kernighan 和 Ritchie C 练习 1-18
Kernighan and Ritchie C exercise 1-18
我试图完成 K&R 书中本练习要求的任务:
Write a program to remove trailing blanks and tabs from each line of input, and to delete entirely blank lines.
第一个任务我还想着怎么实现,第二个任务我有这个想法:
#include <stdio.h>
#define MAXLINE 1000
#define IN 1
#define OUT 1
int blank1(char s[], int len){
int i;
int c=0;
for (i=0; i<len;i++){
if(s[i] == ' ' | s[i] == '\t')
c++;
}
if (c==(len-1))
return 1;
else
return 0;
}
int get_line1(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] = '[=10=]';
return i;
}
int main() {
char line[MAXLINE];
int len;
int j=1;
int i;
while(j){
len=get_line1(line,MAXLINE);
if ((blank1(line,len)) == 0) {
printf("%s", line);
}
if (getchar() == EOF){
j=0;
}
}
}
函数 blank1 将字符串 s[]
和字符串的长度 len
.
作为输入
然后它会循环所有字符串并在每次遇到空白或制表符时增加计数器 i
。如果字符串完全由空格或制表符组成,比如\t\t\t\n[=17=]
,那么i
的值将等于字符串长度的值-1(可以说是字符串的长度不包括字符 \n
的字符串)。如果字符串完全为空,则返回1,否则返回0。所以这样如果blank(string,string's length)
returns 1,我们就知道它是一个完全空的字符串,我们可以避免打印它,因为练习请求。
问题是这个程序在某些输出中删掉了第一个字母。例如:
Once upon a time\n
There was a little monkey\n
That\n
打印出来的是:
Once upon a time
here was a little monke
hat
我无法理解为什么会出现这种截断。
编辑:
#include <stdio.h>
#define MAXLINE 1000
#define IN 1
#define OUT 1
int blank1(char s[], int len){
int i;
int c=0;
for (i=0; i<len;i++){
if(s[i] == ' ' | s[i] == '\t')
c++;
}
if (c==(len-1))
return 1;
else
return 0;
}
int get_line1(char s[], int lim){
int c,i;
for (i=0; i<lim-1 && ((c=getchar())!= EOF) && c!='\n'; i++){
s[i]=c;
}
if (c==EOF)
return -1; /////
if (c=='\n'){
s[i]=c;
i++;
}
s[i] = '[=13=]';
return i;
}
int main() {
char line[MAXLINE];
char verso[MAXLINE];
char longest[MAXLINE];
int len;
int j=1;
int i;
while(j){
len=get_line1(line,MAXLINE);
if (len==-1){ ///////////
j=0;
}
else if ((blank1(line,len)) == 0) {
printf("%s", line);
}
}
}
getchar() == EOF
in main
正在从每一行中吞下你的第一个字符(在第一行之后)。你最好只在一个地方调用 getchar
。
对您当前的实现造成最小改动的一种可能性是将唯一的 getchar
调用保留在 get_line1
和 return -1
中 get_line1
中,如果在那里读取 EOF
,然后在 main
中处理,而不是在 main
.
中调用 getchar
请勿在 main
中使用函数完成类似任务。
char *skipLeadingBlanks(char *str)
{
char *wrk = str;
while((*wrk && *wrk != '\n') && (*wrk == ' ' || *wrk == '\t')) *wrk++;
memmove(str, wrk, strlen(wrk) + 1);
return str;
}
int main(void)
{
char str[1024];
while(fgets(str, sizeof(str), stdin))
{
skipLeadingBlanks(str);
if(!*str || *str == '\n') continue; //empty line
printf("%s",str);
}
}
我试图完成 K&R 书中本练习要求的任务:
Write a program to remove trailing blanks and tabs from each line of input, and to delete entirely blank lines.
第一个任务我还想着怎么实现,第二个任务我有这个想法:
#include <stdio.h>
#define MAXLINE 1000
#define IN 1
#define OUT 1
int blank1(char s[], int len){
int i;
int c=0;
for (i=0; i<len;i++){
if(s[i] == ' ' | s[i] == '\t')
c++;
}
if (c==(len-1))
return 1;
else
return 0;
}
int get_line1(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] = '[=10=]';
return i;
}
int main() {
char line[MAXLINE];
int len;
int j=1;
int i;
while(j){
len=get_line1(line,MAXLINE);
if ((blank1(line,len)) == 0) {
printf("%s", line);
}
if (getchar() == EOF){
j=0;
}
}
}
函数 blank1 将字符串 s[]
和字符串的长度 len
.
然后它会循环所有字符串并在每次遇到空白或制表符时增加计数器 i
。如果字符串完全由空格或制表符组成,比如\t\t\t\n[=17=]
,那么i
的值将等于字符串长度的值-1(可以说是字符串的长度不包括字符 \n
的字符串)。如果字符串完全为空,则返回1,否则返回0。所以这样如果blank(string,string's length)
returns 1,我们就知道它是一个完全空的字符串,我们可以避免打印它,因为练习请求。
问题是这个程序在某些输出中删掉了第一个字母。例如:
Once upon a time\n
There was a little monkey\n
That\n
打印出来的是:
Once upon a time
here was a little monke
hat
我无法理解为什么会出现这种截断。
编辑:
#include <stdio.h>
#define MAXLINE 1000
#define IN 1
#define OUT 1
int blank1(char s[], int len){
int i;
int c=0;
for (i=0; i<len;i++){
if(s[i] == ' ' | s[i] == '\t')
c++;
}
if (c==(len-1))
return 1;
else
return 0;
}
int get_line1(char s[], int lim){
int c,i;
for (i=0; i<lim-1 && ((c=getchar())!= EOF) && c!='\n'; i++){
s[i]=c;
}
if (c==EOF)
return -1; /////
if (c=='\n'){
s[i]=c;
i++;
}
s[i] = '[=13=]';
return i;
}
int main() {
char line[MAXLINE];
char verso[MAXLINE];
char longest[MAXLINE];
int len;
int j=1;
int i;
while(j){
len=get_line1(line,MAXLINE);
if (len==-1){ ///////////
j=0;
}
else if ((blank1(line,len)) == 0) {
printf("%s", line);
}
}
}
getchar() == EOF
in main
正在从每一行中吞下你的第一个字符(在第一行之后)。你最好只在一个地方调用 getchar
。
对您当前的实现造成最小改动的一种可能性是将唯一的 getchar
调用保留在 get_line1
和 return -1
中 get_line1
中,如果在那里读取 EOF
,然后在 main
中处理,而不是在 main
.
getchar
请勿在 main
中使用函数完成类似任务。
char *skipLeadingBlanks(char *str)
{
char *wrk = str;
while((*wrk && *wrk != '\n') && (*wrk == ' ' || *wrk == '\t')) *wrk++;
memmove(str, wrk, strlen(wrk) + 1);
return str;
}
int main(void)
{
char str[1024];
while(fgets(str, sizeof(str), stdin))
{
skipLeadingBlanks(str);
if(!*str || *str == '\n') continue; //empty line
printf("%s",str);
}
}