4
\$\begingroup\$

Exercise 1-17 from the book The C Programming Language: 2nd Edition, K&R

Full description: Write a program to print all input lines that are longer than 80 characters.

#include <stdio.h>

#define MAX_ARRAYCHARACTERS 1000
#define MIN_CHARACTERS 80

int main(void){

    int currchar, // current character being read
        currlinelen = 0; // how many characters in a line

    char characters[MAX_ARRAYCHARACTERS]; // holds all the characters

    while( ( currchar = getchar() ) != EOF ){
        characters[currlinelen] = currchar;
        ++currlinelen;

        if(currchar == '\n'){ // if there is a new line

            if(currlinelen >= MIN_CHARACTERS){ // if the total length of characters of this line is higher than 80
                puts("LINE WITH 80+ CHARACTERS: ");
                for(int thischar = 0; thischar < currlinelen; ++thischar) // print all the characters that were in that line
                    putchar(characters[thischar]);
            }

            currlinelen = 0;
        }
    }


    return 0;
}
\$\endgroup\$
5
\$\begingroup\$

That's too complicated a solution.

It also not only imposes an arbitrary limit on the maximum possible input line length, it fails to check that the input doesn't exceed this limit.

80 is the only significant number in this program. There's no need to worry about anything more than that.

Simply get characters into an 80 character buffer.

If you get '\n' before it fills, empty the buffer.

Otherwise, print the full buffer and get and print characters until the next '\n'.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ awesome! really liked this new approach. I tried it and I came up with this: pastebin.com/XmfQRkxx seems to be working just fine, but I feel that the code is too clunky. if there's any noticeable mistakes, please let me know! \$\endgroup\$ – kibe Dec 8 '19 at 4:31
3
\$\begingroup\$
while( ( currchar = getchar() ) != EOF ){
        characters[currlinelen] = currchar;
        ++currlinelen;

This causes a buffer overflow (and undefined behavior) when the entered string is more than MAX_ARRAYCHARACTERS. A buffer overflow could crash your program, and can cause weird behavior. It is also considered a security vulnerability.

To fix this, I would suggest looking at getline() which is a safer method. Additionally, it doesn't have the 1000 character limit as defined in MAX_ARRAYCHARACTERS. Using this method would greatly simply this code.

++currlinelen;

I would use currlinelen++ instead as this is not being used in an assign operation and doesn't depend on the alternative behavior. It is a bit more readable this way too.

| improve this answer | |
\$\endgroup\$
  • 3
    \$\begingroup\$ Actually preincrement is the faster one and should be preferred (IMHO). Postincrement inherently has to create a copy before incrementing the original (en.cppreference.com/w/cpp/language/operator_incdec). Sure this can be optmized by compiler for integers, but it's a good habit in general, because you don't have to change style when it comes to classes with overloaded operators. \$\endgroup\$ – slepic Dec 6 '19 at 8:47
  • \$\begingroup\$ @slepic C (as this post is tagged) does not have overloaded operators/classes. What is good and idiomatic for one language differs with other languages. The suggestion is a micro optimization and does not improve the order of complexity. Better to focus on the big stuff and let the compiler do it job with the small stuff. It is more productive. In C. ++x vs. x++ is nearly a style issues, as with such, follow your group's style guide. \$\endgroup\$ – chux - Reinstate Monica Dec 8 '19 at 4:17
  • \$\begingroup\$ @chux-ReinstateMonica, I know it's trivial and it makes no difference after compiling and optimization, but I still cringe a little every time I see an unnecessary post-increment. Conceptually, my mind sees ++x as "increment the value of x", while it sees x++ as "save the value of x; increment the value of x; discard the saved value" (which is what ancient compilers actually did). \$\endgroup\$ – Ray Butterworth Dec 8 '19 at 14:53
  • \$\begingroup\$ @RayButterworth Fair enough. I cringe when I see folks trying to out compile a compiler rather than focus on larger issues like buffer overflow protection (as alex did well here) that OP's code lacked. In C, ++currlinelen; and ++currlinelen++; can be expected to emit the same efficient code. It a group felt pre/post was efficient to police, their coding guidelines would address it. I see the issue does not merit the initial comment (hence my comment) and would have not cared had OP/alex coded either way. \$\endgroup\$ – chux - Reinstate Monica Dec 8 '19 at 21:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.