3
\$\begingroup\$

I'm currently learning C with K&R, i'm right now in the exercise 1-22, but it's a little... hard to understand (at least for me). It says:

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 line, and if there are no blanks or tabs before the specified column.

I've done this:

#include <stdio.h>

void seccionar(char to[], char from[])
{
     int a = 0,b = 0, i = 0;
     int max = 0;

     while(from[i] != '\0'){
                   if(max <= 80)
                          to[a] = from[i];
                   if(max == 80){
                          if(to[a] == ' ')
                          to[a] = '\n';
                          else {
                               for(;to[a] != ' '; --a)
                                          ++b;
                               to[a] = '\n';
                               max = 0;
                               a = a + b;}
                               b = 0;
                               }
                   ++a;
                   ++i;
                   ++max;}
     to[a] = '\0';
}
int getline(char s[])
{
    int c, i;

    for(i=0; (c=getchar()) != EOF; ++i){
             s[i] = c;
             if(c == '\n')
             break;}
    ++i;
    s[i] = '\0';
    return i;
}
int main()
{
    char from[10];
    char to[10];
    while(getline(from) > 1){
                       seccionar(to, from);
                       printf("%s", to);}
    return 0;
}

Does this matches with the exercise?

\$\endgroup\$
4
\$\begingroup\$

Potential Buffer Overflows

You've defined from and to to hold only 10 characters apiece, but none of the code actually enforces that, and it appears that you plan on them holding 80 characters or so. You should probably pass the array size to getline, for example, so that it can stop reading either when it reaches a new-line or when it runs out of space in the destination buffer.

Formatting

Your indentation is inconsistent and in places seems rather excessive.

Variable names

Many of your variable names could use some work. Names like a, b and max (that doesn't seem to hold a maximum) could be replaced with much more meaningful names.

Inefficiency

Depending on your viewpoint, there's a fair argument to be made that your code is less efficient than there's any real need for. In particular, it works by reading data into one buffer, then copying all that data to another buffer.

I'd consider a strategy something on this general order:

  1. Read in a line
  2. If it's shorter than the maximum, print it out and go back to 1
  3. Starting from line[max_width], search backward in the string to find a space.
  4. Change that space to a new-line.
  5. Repeat from 2, using the string following the newline you just inserted.
\$\endgroup\$
  • \$\begingroup\$ Is it ok now? just about overflows and inefficiency \$\endgroup\$ – cristch May 27 '16 at 11:07
0
\$\begingroup\$

I've change getline() a little in order to match (i think...) with "potential buffer overflows" and "inefficiency":

int getline(char s[])
{
    int i, max;
    char c;
    max = 0;
    for(i=0; max < 80 && (c=getchar()) != EOF; ++i){
             s[i] = c;
             ++max;
             if(c == '\n')
             break;}
    s[i] = c;
    ++i;
    s[i] = '\0';
    return i;
}

Also, i've changed main() and now from[] and to[] are of 81. 80 normal characters and the last one is for '\0' or '\n'

\$\endgroup\$

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.