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\$
1
  • 3
    \$\begingroup\$ I have rolled back the last edit. Please see What to do when someone answers. \$\endgroup\$ Commented May 27, 2016 at 11:31

2 Answers 2

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\$
1
  • \$\begingroup\$ Is it ok now? just about overflows and inefficiency \$\endgroup\$ Commented May 27, 2016 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\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.