簡體   English   中英

Kernighan 和 Ritchie C 練習 1-18

[英]Kernighan and Ritchie C exercise 1-18

我試圖完成 K&R 書中本練習要求的任務:

編寫一個程序,從輸入的每一行中刪除尾隨的空格和制表符,並刪除完全空白的行。

我仍然需要弄清楚如何實現第一個任務,但我對第二個任務有這個想法:

#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] = '\0';
     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\\0 ,則i的值將與字符串的長度相同 - 1(可以說,長度為不包括字符\\n的字符串)。 如果字符串完全為空,則返回 1,否則返回 0。所以這樣如果blank(string,string's length)返回 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] = '\0';
    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和返回-1get_line1如果EOF讀那里,然后被內部處理main ,而不是調用getchar內部main

不要在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);
    }
}

https://godbolt.org/z/hxW5zP5Mx

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM