I'm a very amateur programmer working his way through K&R's 'The C Programming language'. I'm on the character arrays section of the first chapter, and I'm trying to do one of the recommended exercises.
I had already made a program that worked, but the problem was that it worked immediately, so I had to write all my test input text separately then paste it into the terminal.
The original program in the book has a property where the program only outputs text once the EOF character has been found. I wanted to replicate that in my program, and the only way I could think to do that was storing it all in one array. One hour later and this was the result, but I can't for the life of me figure out why it isn't working.
The program only outputs the first line that is longer than 80 characters.
Help would be appreciated.
1 #include <stdio.h>
2 #define MAXLINE 1000 /* maximum input line */
3 #define MINLENGTH 80 /* minimum length of an output line */
4
5 int getlone(char line[], int maxline);
6 int append(char to[], char from[], int i);
7
8 /* print all input lines longer than 80 characters*/
9 int main(){
10 int len; /* current line length */
11 int outlen; /*length of all output lines so far*/
12 char line[MAXLINE]; /* current input line */
13 char printlines[MAXLINE]; /*all output lines*/
14
15 while((len = getlone(line, MAXLINE)) > 0){
16 if (len > MINLENGTH){
17 outlen = append(printlines, line, outlen);
18 }
19 }
20 printlines[outlen] = '\0';
21 printf("%s", printlines);
22 return 0;
23 }
24
25 /*getline: read a line into s, return length*/
26 int getlone(char s[], int lim){
27 int c, i;
28 for(i=0; i < lim-1 && (c = getchar()) != EOF && c != '\n'; i++){
29 s[i] = c;
30 }
31
32 if (c == '\n') {
33 s[i] = c;
34 i++;
35 }
36 return i;
37 }
38
39 /* append: adds line to the end of a character array*/
40 int append(char to[], char from[], int i){
41 while((to[i] = from[i]) != '\n')
42 i++;
43 return i++;
44 }
45
First off, well done for working through the classic K&R book. That's how I learned C programming too.
Your problem stems from two problems:
The index to the array returned by append()
returns 1 past the last point written. Which is one past a likely zero, as arrays are typically (in modern C) initialized with zeros in each character. And zero is telling the print statement to stop printing.
You're not initializing outlen
to zero, and unlike arrays it can get filled with a random value (potentially).
You're copying from another string (char array) starting at the index of the multiline instead of the line.
To demonstrate, consider this code
#include <stdio.h>
#define MAXLINE 1000 /* maximum input line */
/* append: adds line to the end of a character array*/
int append(char to[], char from[], int i){
while((to[i] = from[i]) != '\n')
i++;
return i++;
}
int main() {
char printlines[MAXLINE];
int outlen = 0;
outlen = append(printlines, "foo", outlen);
outlen = append(printlines, "bar", outlen);
printf("multi: %s\n", printlines);
}
This code when run will only print "foo". But if you look at the bytes in the actual array using gdb, you'll see that bar is there, but one spot too far:
(gdb) p printlines[0]
$1 = 102 'f'
(gdb) p printlines[2]
$2 = 111 'o'
(gdb) p printlines[3]
$3 = 0 '\000'
(gdb) p printlines[4]
$4 = 98 'b'
Or using the better x
command in gdb:
(gdb) x/8b printlines
0x7fffffffced0: 0x66 0x6f 0x6f 0x00 0x62 0x61 0x72 0x00
This actually works:
#include <stdio.h>
#define MAXLINE 1000 /* maximum input line */
/* append: adds line to the end of a character array*/
int append(char to[], char from[], int i){
int j = 0;
while((to[i] = from[j]) != '\n') {
i++;
j++;
}
return i+1;
}
int main() {
char printlines[MAXLINE];
int outlen = 0;
printf("outlen: %d\n", outlen);
outlen = append(printlines, "foo\n", outlen);
printf("outlen: %d\n", outlen);
outlen = append(printlines, "bar\n", outlen);
printf("outlen: %d\n", outlen);
printf("multi: %s\n", printlines);
}
Final note: your code is subject to buffer overflows. You should always keep track of the length of an array used, and pass this into any functions to make sure you don't overwrite the end of the array. Consider a file with 20 80-line lines. This will be larger than your 1000 limit, but your program will still attempt to write beyond it (and will crash).