Thread: Need help with an exersice in K&R c

  1. #1
    Registered User
    Join Date
    Sep 2016
    Posts
    7

    Need help with an exersice in K&R c

    The quesion is to write a program to print all input lines that are longer than 80 chars long

    this is my attempt at solution

    http://vpaste.net/JmxgH
    Last edited by karthy; 09-12-2016 at 02:25 PM.

  2. #2
    Registered User
    Join Date
    Sep 2014
    Posts
    364
    You can post your code in code-tags.

    Code:
    #include <stdio.h>
    
    #define MAXLEN 1000
    
    int get_line(char line[], int max);
    void copy(char to[], char from[], int null_count, int length);
    void print(char line[]);
    
    int main() {
    
        char current_line[MAXLEN];
        char line[MAXLEN];
        int null_count = 0;
        int length = 0;
    
        while(length = get_line(current_line, MAXLEN) > 0) {
            ++null_count;
            if(length >= 80) {
                copy(line, current_line, null_count, length);
            }
        }
        print(line);
    }
    
    int get_line(char line[], int max) {
    
        int i,c;
        for(i = 0,c = 0; i < max-1 && (c = getchar()) != EOF && c != '\n'; ++i) 
            line[i] = c;
        if(c == '\n') 
            line[i] = '\0';
        else {
            line[i] = '\0';
            line[i+1] = '0';
            i = i + 2;
        }
    
        return i;
    }
    
    void copy(char to[], char from[], int null_count, int length) {
    
        int i = 0;
    
        while((null_count-1) != 0) {
            ++i;
            if(from[i] == '\0') {
                --null_count;
            }
        }
    
        if(i == 0) {
            while(i != (length+1)) {
                to[i] = from[i];
                ++i;
            }
        }
        else {
            int x;
            int y = i;
            for(x = 0; x != i+1; ++x) {
                to[y++] = from[x];
            }
        }
    }
    
    void print(char line[]) {
    
        int i = 0;
    
        while((line[i] == '\0' && line[i+1] == '\0')) {
            printf("%c",line[i]);
            if(line[i] == '\0')
                printf("\n");
            ++i;
        }
    }
    First, you wrote the code in a nice style and is perfect readable.
    I have compiled it and the output is:
    Code:
    $ gcc -Wall lines.c -o lines
    lines.c: In function ‘main’:
    lines.c:16:5: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
         while(length = get_line(current_line, MAXLEN) > 0) {
         ^
    lines.c:23:1: warning: control reaches end of non-void function [-Wreturn-type]
     }
     ^
    To fix the problems, edit line 16 to
    Code:
    …
        while((length = get_line(current_line, MAXLEN)) > 0) {
    …
    and insert 'return 0;' at the end of main (line 23).
    After that, i inserted
    Code:
    …
            printf("lenght: %d / null_count: %d\n", length, null_count);
    …
    on line 18.

    Now, the output is:
    Code:
    $ ./lines 
    abcde
    lenght: 5 / null_count: 1
    abc
    lenght: 3 / null_count: 2
    0123456789
    lenght: 10 / null_count: 3
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    $
    I don't think that this is what you want, but the output of information will show you important things.
    Last edited by WoodSTokk; 09-12-2016 at 03:22 PM.
    Other have classes, we are class

  3. #3
    Registered User
    Join Date
    Sep 2016
    Posts
    7
    i have fixed those errors and changed the else block in get_line function now if the first string is more than 80 chars it works ,If any string other than first is above 80 it doesnt print that and i need to issue two EOF's using ctrl+D and hit enter for it to work cant figure out where the problem is
    here is the updated code i cant get the code tag to work in this webside
    all the code formatting and indentaion gets thrown off
    http://vpaste.net/u39Yw
    Last edited by karthy; 09-13-2016 at 06:03 AM.

  4. #4
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,127
    As @WoodSTokk has said above, you need to post the code HERE using Code Tags! Please read the Forum Rules before posting again.

    You are asking for help, but force us to go to another site to see the code.

  5. #5
    Registered User
    Join Date
    Sep 2016
    Posts
    7
    Code:
    #include <stdio.h>
    
    #define MAXLEN 1000
    
    int get_line(char line[], int max);
    void copy(char to[], char from[], int null_count, int length);
    void print(char line[]);
    
    int main() {
    
        char current_line[MAXLEN];
        char line[MAXLEN];
        int null_count = 0;
        int length = 0;
    
        while((length = get_line(current_line, MAXLEN)) > 0) {
            if(length >= 80) {
                ++null_count;
                copy(line, current_line, null_count, length);
            }
        }
        printf("lenght: %d / null_count: %d\n", length, null_count);
        print(line);
        return 0;
    }
    
    int get_line(char line[], int max) {
    
        int i,c;
        for(i = 0,c = 0; i < max-1 && (c = getchar()) != EOF && c != '\n'; ++i) 
            line[i] = c;
        if(c == '\n') 
            line[i] = '\0';
        else if(c == EOF) {
            line[i] = '\0';
            line[i+1] = '\0';
            i = i + 2;
        }
    
        return i;
    }
    
    void copy(char to[], char from[], int null_count, int length) {
    
        int i = 0;
    
        while((null_count-1) != 0) {
            ++i;
            if(from[i] == '\0') {
                --null_count;
            }
        }
    
        if(i == 0) {
            while(i != (length+1)) {
                to[i] = from[i];
                ++i;
            }
        }
        else {
            int x;
            int y = i;
            for(x = 0; x != i+1; ++x) {
                to[++y] = from[x];
            }
        }
    }
    
    void print(char line[]) {
    
        int i = 0;
    
        while(line[i] != '\0' && line[i+1] != '\0') {
            if(line[i] != '\0')
            printf("%c",line[i]);
            else
                printf("\n");
            ++i;
        }
        
    }
    Last edited by karthy; 09-13-2016 at 07:27 AM.

  6. #6
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,127
    For starters, in main(), you are only copying current_line into line IF the length is greater than 80! NEVER for short lines.

    Also, please examine the code in copy(). It seems more complicated than needed, with possible bugs. Use a pencil and paper to step through the code for all cases of calling copy(). I can take a further look at it later. Got to go now!

  7. #7
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Here's a rewrite of your code that seems to work.
    Code:
    #include <stdio.h>
     
    #define MAXBUFFER    100000
    #define MAXLINE        1000
    #define PRINT_LENGTH     10    // short length for testing
    
    int get_line(char line[], int max);
    void append_line(char to[], char from[], int line_count, int length);
    void print_lines(char lines[]);
     
    int main() {
        char current_line[MAXLINE], lines[MAXBUFFER];
        int line_count = 0, length = 0;
        while ((length = get_line(current_line, MAXLINE)) > 0)
            if (length >= PRINT_LENGTH)
                append_line(lines, current_line, line_count++, length);
        print_lines(lines);
        return 0;
    }
    
    int get_line(char line[], int max) {
        int i = 0, c = 0;
        while (i < max - 1 && (c = getchar()) != EOF && c != '\n')
            line[i++] = c;
        line[i] = '\0';
        return i;
    }
     
    void append_line(char to[], char from[], int line_count, int length) {
        int i = 0, j = 0;
        while (line_count > 0)
            if (to[i++] == '\0')
                line_count--;
        while (i < MAXBUFFER - 2 && j < length)
            to[i++] = from[j++];
        to[i] = to[i+1] = '\0';
    }
     
    void print_lines(char lines[]) {
        int i;
        for (i = 0; lines[i] != '\0' || lines[i+1] != '\0'; i++)
            putchar(lines[i] ? lines[i] : '\n');
        putchar('\n');
    }
    But your code is overcomplicated for the task. The following solves it using a buffer of PRINT_LENGTH + 1 and has no line-length (or buffer-length) restrictions.
    Code:
    #include <stdio.h>
    
    #define PRINT_LENGTH 10   // short length for testing
    
    int main(void) {
        char buf[PRINT_LENGTH + 1] = {0};
        int c = 0;
    
        while (c != EOF) {
            int i = 0;
            while ((c = getchar()) != EOF && c != '\n' && i < PRINT_LENGTH)
                buf[i++] = c;
    
            if (i == PRINT_LENGTH) {
                printf("%s", buf);
                while (c != EOF && c != '\n') {
                    putchar(c);
                    c = getchar();
                }
                putchar('\n');
            }
        }
    
        return 0;
    }

Popular pages Recent additions subscribe to a feed

Tags for this Thread