Skip to main content
Describe the purpose rather than just a pointer in the title; removed image of text
Source Link
Toby Speight
  • 81.7k
  • 14
  • 101
  • 308

The solution for the exercise Fold long lines (K&R2 Exercise 1-22 from the book "The C programming language" K&R2)

The exercise

Github linkGithub link

The solution for the exercise 1-22 from the book "The C programming language" K&R2

The exercise

Github link

Fold long lines (K&R2 Exercise 1-22)

Github link

Tweeted twitter.com/StackCodeReview/status/1360242300320948237
Task should be plain text - also fix formatting of code block
Source Link

My solution : https://github.com/AhmedAlaa-10/The-C-programming-language.-k-R-2-solutions-by-me/blob/main/Chap.%201/ex22.c

Exercise 1-22. Write a program to "fold" long input lines into two or more shorter lines after the last non-blank character that occurs before the n-th column of input. Make sure your program does something intelligent with very long lines, and if there are no blanks or tabs before the specified column.


 #include <stdio.h> 

#define LINE_MAX_SIZE 21        /* The maximum number of columns allowed in a single line */
#define IN_NON_BLANK_SEQ 1      /* Indicate that a sequence of non-blank character are being processed */ 
#define TAP_STOP_DIST 5

#define NON_BLANK(ch)   (ch != '\t' && ch != '\n' && ch != ' ') 

int get_next_tap_pos(int current_column) {
    // columns numbered 0, 1, 2... there is a tap stop at 0, 5, 10, 15, 20
    return current_column / TAP_STOP_DIST * TAP_STOP_DIST + TAP_STOP_DIST; 
}

int main(void) 
{
    char block[LINE_MAX_SIZE+1];
    int column_pos = 0;                 /* Indicate the current column in the output where the next character will be printed*/
    int index_non_blank = 0;            /* Indicate the number of the non-blank char in the next non-blank char sequence */ 
    int state = !IN_NON_BLANK_SEQ;      /* Indicate whether a non-blank character is being processed */ 

    int ch; 
    while ( (ch = getchar()) != EOF) {
        if (NON_BLANK(ch)) {

            state = IN_NON_BLANK_SEQ; 
            if (index_non_blank == LINE_MAX_SIZE) {
                // There is a word bigger than the size of the line
                block[LINE_MAX_SIZE] = '\0'; 
                // Should I print it in the current line or in the next line ?
                // Our word is as big as our line. so if current line is not empty, we can't print it here
                if (column_pos != 0) 
                    putchar('\n');
                printf("%s\n", block); 
                column_pos = 0; 
                index_non_blank = 0;
                block[index_non_blank] = ch;  
            }
            else {
                block[index_non_blank] = ch; 
                ++index_non_blank; 
            }
        }
        else {
            // Is there a non-blank sequence that just finished ?
            if (state == IN_NON_BLANK_SEQ) {
                // Should the current word be printed in the current line or next line ?
                block[index_non_blank] = '\0'; 
                int expected_column_num = column_pos + index_non_blank; 
                if (expected_column_num <= LINE_MAX_SIZE) {
                    printf("%s", block); 
                    column_pos = expected_column_num; 
                }
                else {
                    putchar('\n'); 
                    printf("%s", block); 
                    column_pos = index_non_blank; 
                }

                state = !IN_NON_BLANK_SEQ;  
                index_non_blank = 0; 
            }
            // now print the whitespace character and update column position 
            if (ch == '\n') {
                putchar(ch); 
                column_pos = 0; 
            }
            else if (ch == ' ' && column_pos < LINE_MAX_SIZE) {
                putchar(ch); 
                ++column_pos; 
            }
            else if (ch == '\t' && column_pos < LINE_MAX_SIZE) {
                putchar(ch); 
                column_pos = get_next_tap_pos(column_pos); 
            }
            else {
                putchar('\n');
                column_pos = 0;  
            }
        }
    }
}
```

Github link

My solution : https://github.com/AhmedAlaa-10/The-C-programming-language.-k-R-2-solutions-by-me/blob/main/Chap.%201/ex22.c


 #include <stdio.h> 

#define LINE_MAX_SIZE 21        /* The maximum number of columns allowed in a single line */
#define IN_NON_BLANK_SEQ 1      /* Indicate that a sequence of non-blank character are being processed */ 
#define TAP_STOP_DIST 5

#define NON_BLANK(ch)   (ch != '\t' && ch != '\n' && ch != ' ') 

int get_next_tap_pos(int current_column) {
    // columns numbered 0, 1, 2... there is a tap stop at 0, 5, 10, 15, 20
    return current_column / TAP_STOP_DIST * TAP_STOP_DIST + TAP_STOP_DIST; 
}

int main(void) 
{
    char block[LINE_MAX_SIZE+1];
    int column_pos = 0;                 /* Indicate the current column in the output where the next character will be printed*/
    int index_non_blank = 0;            /* Indicate the number of the non-blank char in the next non-blank char sequence */ 
    int state = !IN_NON_BLANK_SEQ;      /* Indicate whether a non-blank character is being processed */ 

    int ch; 
    while ( (ch = getchar()) != EOF) {
        if (NON_BLANK(ch)) {

            state = IN_NON_BLANK_SEQ; 
            if (index_non_blank == LINE_MAX_SIZE) {
                // There is a word bigger than the size of the line
                block[LINE_MAX_SIZE] = '\0'; 
                // Should I print it in the current line or in the next line ?
                // Our word is as big as our line. so if current line is not empty, we can't print it here
                if (column_pos != 0) 
                    putchar('\n');
                printf("%s\n", block); 
                column_pos = 0; 
                index_non_blank = 0;
                block[index_non_blank] = ch;  
            }
            else {
                block[index_non_blank] = ch; 
                ++index_non_blank; 
            }
        }
        else {
            // Is there a non-blank sequence that just finished ?
            if (state == IN_NON_BLANK_SEQ) {
                // Should the current word be printed in the current line or next line ?
                block[index_non_blank] = '\0'; 
                int expected_column_num = column_pos + index_non_blank; 
                if (expected_column_num <= LINE_MAX_SIZE) {
                    printf("%s", block); 
                    column_pos = expected_column_num; 
                }
                else {
                    putchar('\n'); 
                    printf("%s", block); 
                    column_pos = index_non_blank; 
                }

                state = !IN_NON_BLANK_SEQ;  
                index_non_blank = 0; 
            }
            // now print the whitespace character and update column position 
            if (ch == '\n') {
                putchar(ch); 
                column_pos = 0; 
            }
            else if (ch == ' ' && column_pos < LINE_MAX_SIZE) {
                putchar(ch); 
                ++column_pos; 
            }
            else if (ch == '\t' && column_pos < LINE_MAX_SIZE) {
                putchar(ch); 
                column_pos = get_next_tap_pos(column_pos); 
            }
            else {
                putchar('\n');
                column_pos = 0;  
            }
        }
    }
}
```

Exercise 1-22. Write a program to "fold" long input lines into two or more shorter lines after the last non-blank character that occurs before the n-th column of input. Make sure your program does something intelligent with very long lines, and if there are no blanks or tabs before the specified column.

#include <stdio.h> 

#define LINE_MAX_SIZE 21        /* The maximum number of columns allowed in a single line */
#define IN_NON_BLANK_SEQ 1      /* Indicate that a sequence of non-blank character are being processed */ 
#define TAP_STOP_DIST 5

#define NON_BLANK(ch)   (ch != '\t' && ch != '\n' && ch != ' ') 

int get_next_tap_pos(int current_column) {
    // columns numbered 0, 1, 2... there is a tap stop at 0, 5, 10, 15, 20
    return current_column / TAP_STOP_DIST * TAP_STOP_DIST + TAP_STOP_DIST; 
}

int main(void) 
{
    char block[LINE_MAX_SIZE+1];
    int column_pos = 0;                 /* Indicate the current column in the output where the next character will be printed*/
    int index_non_blank = 0;            /* Indicate the number of the non-blank char in the next non-blank char sequence */ 
    int state = !IN_NON_BLANK_SEQ;      /* Indicate whether a non-blank character is being processed */ 

    int ch; 
    while ( (ch = getchar()) != EOF) {
        if (NON_BLANK(ch)) {

            state = IN_NON_BLANK_SEQ; 
            if (index_non_blank == LINE_MAX_SIZE) {
                // There is a word bigger than the size of the line
                block[LINE_MAX_SIZE] = '\0'; 
                // Should I print it in the current line or in the next line ?
                // Our word is as big as our line. so if current line is not empty, we can't print it here
                if (column_pos != 0) 
                    putchar('\n');
                printf("%s\n", block); 
                column_pos = 0; 
                index_non_blank = 0;
                block[index_non_blank] = ch;  
            }
            else {
                block[index_non_blank] = ch; 
                ++index_non_blank; 
            }
        }
        else {
            // Is there a non-blank sequence that just finished ?
            if (state == IN_NON_BLANK_SEQ) {
                // Should the current word be printed in the current line or next line ?
                block[index_non_blank] = '\0'; 
                int expected_column_num = column_pos + index_non_blank; 
                if (expected_column_num <= LINE_MAX_SIZE) {
                    printf("%s", block); 
                    column_pos = expected_column_num; 
                }
                else {
                    putchar('\n'); 
                    printf("%s", block); 
                    column_pos = index_non_blank; 
                }

                state = !IN_NON_BLANK_SEQ;  
                index_non_blank = 0; 
            }
            // now print the whitespace character and update column position 
            if (ch == '\n') {
                putchar(ch); 
                column_pos = 0; 
            }
            else if (ch == ' ' && column_pos < LINE_MAX_SIZE) {
                putchar(ch); 
                ++column_pos; 
            }
            else if (ch == '\t' && column_pos < LINE_MAX_SIZE) {
                putchar(ch); 
                column_pos = get_next_tap_pos(column_pos); 
            }
            else {
                putchar('\n');
                column_pos = 0;  
            }
        }
    }
}

Github link

Source Link

The solution for the exercise 1-22 from the book "The C programming language" K&R2

The exercise

My solution : https://github.com/AhmedAlaa-10/The-C-programming-language.-k-R-2-solutions-by-me/blob/main/Chap.%201/ex22.c

The key idea is that I process whitespace character by character while processing a sequence of non-blank characters block by block, i.e. I read a block then decide whether to print it in the current line or next line.


#include <stdio.h> 

#define LINE_MAX_SIZE 21        /* The maximum number of columns allowed in a single line */
#define IN_NON_BLANK_SEQ 1      /* Indicate that a sequence of non-blank character are being processed */ 
#define TAP_STOP_DIST 5

#define NON_BLANK(ch)   (ch != '\t' && ch != '\n' && ch != ' ') 

int get_next_tap_pos(int current_column) {
    // columns numbered 0, 1, 2... there is a tap stop at 0, 5, 10, 15, 20
    return current_column / TAP_STOP_DIST * TAP_STOP_DIST + TAP_STOP_DIST; 
}

int main(void) 
{
    char block[LINE_MAX_SIZE+1];
    int column_pos = 0;                 /* Indicate the current column in the output where the next character will be printed*/
    int index_non_blank = 0;            /* Indicate the number of the non-blank char in the next non-blank char sequence */ 
    int state = !IN_NON_BLANK_SEQ;      /* Indicate whether a non-blank character is being processed */ 

    int ch; 
    while ( (ch = getchar()) != EOF) {
        if (NON_BLANK(ch)) {

            state = IN_NON_BLANK_SEQ; 
            if (index_non_blank == LINE_MAX_SIZE) {
                // There is a word bigger than the size of the line
                block[LINE_MAX_SIZE] = '\0'; 
                // Should I print it in the current line or in the next line ?
                // Our word is as big as our line. so if current line is not empty, we can't print it here
                if (column_pos != 0) 
                    putchar('\n');
                printf("%s\n", block); 
                column_pos = 0; 
                index_non_blank = 0;
                block[index_non_blank] = ch;  
            }
            else {
                block[index_non_blank] = ch; 
                ++index_non_blank; 
            }
        }
        else {
            // Is there a non-blank sequence that just finished ?
            if (state == IN_NON_BLANK_SEQ) {
                // Should the current word be printed in the current line or next line ?
                block[index_non_blank] = '\0'; 
                int expected_column_num = column_pos + index_non_blank; 
                if (expected_column_num <= LINE_MAX_SIZE) {
                    printf("%s", block); 
                    column_pos = expected_column_num; 
                }
                else {
                    putchar('\n'); 
                    printf("%s", block); 
                    column_pos = index_non_blank; 
                }

                state = !IN_NON_BLANK_SEQ;  
                index_non_blank = 0; 
            }
            // now print the whitespace character and update column position 
            if (ch == '\n') {
                putchar(ch); 
                column_pos = 0; 
            }
            else if (ch == ' ' && column_pos < LINE_MAX_SIZE) {
                putchar(ch); 
                ++column_pos; 
            }
            else if (ch == '\t' && column_pos < LINE_MAX_SIZE) {
                putchar(ch); 
                column_pos = get_next_tap_pos(column_pos); 
            }
            else {
                putchar('\n');
                column_pos = 0;  
            }
        }
    }
}
```