Reputation: 4623
Exercise 1-22 of The C Programming Language is as follow:
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.
This is the code:
#include <ctype.h>
#include <stdio.h>
#define MAXLINE 500
#define FOLD_LENGTH 15
/* _getline: read a line into s, return length */
size_t _getline(char s[], int lim)
{
int c;
size_t i;
for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
int main()
{
int c;
char line[MAXLINE];
char temp;
unsigned last_space_idx = 0, i, offset = 0;
while (_getline(line, MAXLINE) != 0) {
for (i = 0; line[offset+i] != '\0'; i++) {
if (i == FOLD_LENGTH) {
temp = line[offset+last_space_idx];
line[offset+last_space_idx] = '\0';
printf("%s\n", line+offset);
line[offset+last_space_idx] = temp;
offset = last_space_idx;
i = 0;
continue;
}
if (isspace(line[offset+i])) {
last_space_idx = offset+i;
}
}
printf("%s\n", line+offset);
}
return 0;
}
This is the sample input I'm using:
Penny Lane is in my ears and in my eyes There beneath the blue suburban skies
And this is the output I get:
Penny Lane is in my ears and in my ey and in my eyes eyes eyes eyes
What's the bug here? I really have no clue.
Upvotes: 3
Views: 442
Reputation: 4928
Lots of errors. You do this:
last_space_idx = offset+i;
But you also do this:
temp = line[offset+last_space_idx];
Which means that temp = line[(2 * offset) + last_observed_space_relative_to_offset]
.
You also do this:
offset = last_space_idx;
That means the offset becomes equal to the last observed space, so you'll have a preceding space on every line after the first, like this:
Penny lane is
in my ears
and in my eyes
Your _getline() method does this:
if (c == '\n') {
s[i] = c;
++i;
}
That means any line returns are preserved, so if you have There beneath\nthe blue suburban skies
as the input you'll get this output:
There beneath
the blue suburban skies
Lastly, each new line you read uses the last space index and offset from the previous line. You need to reset them before the for
loop starts.
Here's a fixed version. I've tidied up the style a little and replaced the printf() bodge with a string format that will print a substring.
#include <stdio.h>
#include <ctype.h>
#include <stdio.h>
#define MAXLINE 500
#define FOLD_LENGTH 15
size_t _getline(char s[], int lim);
/* _getline: read a line into s, return length */
size_t _getline(char s[], int lim) {
char c;
size_t i;
for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i) {
s[i] = c;
}
s[i] = '\0';
return i;
}
int main() {
char line[MAXLINE];
unsigned last_space_idx = 0;
unsigned i;
unsigned offset = 0;
while (_getline(line, MAXLINE) != 0) {
last_space_idx = 0;
offset = 0;
for (i = 0; line[offset+i] != '\0'; ++i) {
if (i == FOLD_LENGTH) {
printf("%.*s\n", last_space_idx, line + offset);
offset += last_space_idx + 1;
i = 0;
} else if (isspace(line[offset + i])) {
last_space_idx = i;
}
}
printf("%s\n", line + offset);
}
return 0;
}
Upvotes: 8