K&R C Programming Language Exercise 1-16 - c

So I'm working on learning C by going through The C Programming Language and trying to do the exercises as I go. Exercise 1-16 seems really simple as it's just making an edit to a program that is already given.
What I can't figure out is why I can't get the code from the book, or from any of the online solutions to this exercise to compile... Everything I've tried throws an error that says: "error: conflicting types for ‘getline’"
Here's the original code from the book:
/* Write a program to print all input lines that are longer than 80 characters. */
#include <stdio.h>
#define MAXLINE 1000 /* maximum input line size */
int getline(char line[], int maxline);
void copy(char to[], char from[]);
int main ()
{
int len; /* current line length */
int max; /* maximum line length seen so far */
char line[MAXLINE]; /* current input line */
char longest[MAXLINE]; /* longest line saved here */
max = 0;
while ((len = getline(line, MAXLINE)) > 0)
if (len > max) {
max = len;
copy(longest, line);
}
if (max > 0) /* there was a line */
printf("%s", longest);
return 0;
}
/* getline: read a line into s, return length */
int getline(char s[], int lim)
{
int c, 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;
}
/* copy: copy 'from' into 'to'; assume to is big enough */
void copy(char to[], char from[])
{
int i;
i = 0;
while ((to[i] = from[i]) != '\0')
++i;
}
Any glaringly obvious mistakes here? Is it just my machine or how I'm trying to compile it?

Related

Why does this program in Dennis Ritchie's "The C Programming Language" not work?

I'm starting to learn C and came across the following program in Dennis Ritchie's The C Programming Language (2nd edition):
#include <stdio.h>
#define MAXLINE 1000
int getline(char line[], int maxline);
void copy(char to[], char from[]);
int main()
{
int len;
int max;
char line[MAXLINE]; /* current input line */
char longest[MAXLINE]; /* longest line saved here */
max = 0;
while ((len = getline(line, MAXLINE)) > 0)
{
if (len > max)
{
max = len;
copy(longest, line);
}
}
if (max > 0)
printf("%s", longest);
return 0;
}
int getline(char s[], int lim)
{
int c, 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;
}
void copy(char to[], char from[])
{
int i;
i = 0;
while ((to[i] = from[i]) != '\0')
++i;
}
When I run this program exactly as is, it does not compile because there are conflicting definitions of getline. It turns out there is a getline in stdio.h, and that's where the conflict comes from. I assume this is non-standard or was added to the library after the book was published. In any case, that error was easily fixed by simply changing the name of the function to getLine.
After making that change, the program compiles but never actually completes. What I did notice is that getLine adds both a newline character and a null terminator (\0) to the character array s, and the value it returns, while it is meant to be the length of the character array, is actually that length + 1. Modifying the function to return i - 1 instead of i fixes the issue.
My question is: why does it fix the issue? I doubt that it's a typo, but maybe that's possible? Or could it be a compiler issue? Do some compilers count a null terminator as a character (i.e. to be included in the length of the character array) while others don't?
I should also say that I'm using an M1 MacBook, so I guess it's possible that the code translates to different machine code which creates different results?
EDIT:
The following is the modified code that works for me:
#include <stdio.h>
#define MAXLINE 1000
int getLine(char line[], int maxline);
void copy(char to[], char from[]);
int main()
{
int len;
int max;
char line[MAXLINE]; /* current input line */
char longest[MAXLINE]; /* longest line saved here */
max = 0;
while ((len = getLine(line, MAXLINE)) > 0)
{
if (len > max)
{
max = len;
copy(longest, line);
}
}
if (max > 0)
printf("%s", longest);
return 0;
}
int getLine(char s[], int lim)
{
int c, 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 - 1;
}
void copy(char to[], char from[])
{
int i;
i = 0;
while ((to[i] = from[i]) != '\0')
++i;
}
Also, when I say that the original code never completes, I mean that I can type anything, press enter, type some more, press enter, etc. then finally just press enter without typing (the code is checking for an array of length zero, so this is where it should print out the line of max length and exit), and the program continues running.
When I run this program exactly as is, it does not compile because there are conflicting definitions of getline
There is a getline function offered as an extension in some implementations, and its prototype is conflicting with the example in the book. That's most likely what's happening with you. Awesome as K&R is, it's an old book at this point and out of date in many respects.
The easiest way to get around this is to rename your getline function to getLine or get_line or something else. Alternately you'll need to undefine _GNU_SOURCE or _POSIX_C_SOURCE before including stdio.h, either in your code or on the command line.

Error in C program that I don't understand [duplicate]

This question already has an answer here:
Unable to compile sample code from The C Programming Language 2nd , page 29
(1 answer)
Closed 2 years ago.
I just started out learning C with "The C Programming Language" book. I have an experience in programming mainly in python so I'm not new and I usually understand errors and fix them, but this time I really don't understand what's wrong with the C program that I just copied from the book to get some practice.
#include <stdio.h>
#define MAXLINE 1000 /*Maximum input of the line size*/
int getline(char line[], int maxline);
void copy(char to[], char from[]);
/*Print longest input line*/
int main()
{
int len; //Current line size
int max; //The max lenght seen so far
char line[MAXLINE]; //Current input line
char longest[MAXLINE]; //longest line saved here
max = 0;
while ((len = getline(line, MAXLINE)) > 0)
if (len > max)
{
max = len;
copy(longest, line);
}
if (max > 0) //There was a line
printf("%s", longest);
return 0;
}
/* getline: read a line into s and return its lenght */
int getline(char s[], int lim)
{
int c, 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;
}
/* copy: copy 'from' into 'to'; assume 'to' is big enough */
void copy(char to[], char from[])
{
int i;
i = 0;
while ((to[i] = from[i]) != '\0')
++i;
}
And here is the error message:
error: conflicting types for 'getline'
The problem is that getline() is (now) a standard POSIX library function (defined in <stdio.h>). Your function has the same name and is thus clashing with it.
The solution is to simply change the name.

What exactly breaks the while loop in main?

What exactly breaks the while loop in this code? This is code from the book The C Programming Language from the C creators. It is a code from section 1.9. I guess int len will always be bigger than 0, but somehow when I compile this code the while loop breaks when I press Ctrl+Z (which is EOF for Windows).
#include <stdio.h>
#define MAXLINE 1000 /* maximum input line length */
int mgetline(char line[], int maxline);
void copy(char to[], char from[]);
/* print the longest input line */
main() {
int len; /* current line length */
int max; /* maximum length seen so far */
char line[MAXLINE]; /* current input line */
char longest[MAXLINE]; /* longest line saved here */
max = 0;
while ((len = mgetline(line, MAXLINE)) > 0)
if (len > max) {
max = len;
if (max == len)
copy(longest, line);
}
if (max > 0) /* there was a line */
printf("%s", longest);
return 0;
}
/* mgetline: read a line into s, return length */
int mgetline(char s[], int lim) {
int c, 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;
}
/* copy: copy 'from' into 'to'; assume to is big enough */
void copy(char to[], char from[]) {
int i;
i = 0;
while ((to[i] = from[i]) != '\0')
++i;
}
Loop 1: (In copy)
Strings in C are NUL-terminated by convention. NUL is a special char value with the value 0.
The value of the expression to[i] = from[i] is the new value of to[i].
That is 0 when NUL is reached, and the loop exits.
Loop 2: (In main)
Similarly the value of len = mgetline(line, MAXLINE) is the new value of len. That is 0 if mgetline returns 0 which is does when no characters are read. So that loop exits.

Can't print out a string in C

I've been learning C with a book and I tried one of its programs on my Linux PC with gcc, but for some reason it doesn't work.
#include <stdio.h>
#define MAXLINE 1000
int getoneline(char line[], int maxline);
void copy(char to[], char from[]);
int main()
{
int line_length, max_length;
char line[MAXLINE];
char longest[MAXLINE];
max_length = 0;
while ((line_length=getoneline(line, MAXLINE)) > 0)
if (line_length > max_length)
{
max_length = line_length;
copy(longest, line);
}
if (max_length > 0)
printf ("%s", longest);
return 0;
}
int getoneline(char s[], int limit)
{
int c, i;
for (i=0; i < limit - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
void copy(char to[], char from[])
{
int i;
i = 0;
while((to[i] = from[i]) != '\0')
++i;
}
It is the same in the book and it's supposed to find the longest line in some text and the output it. However, nothing gets outputted, as if the variable longest disappeared after the while loop. I can print it inside, though, but that's not what I want.
What's going wrong?
Works for me! Try running the program and entering a few lines of text. Then press Ctrl-D so that getchar returns an EOF, causing the program to break out of the while loop and print the longest line
I would point out that there are about a million better ways to write this code that are less confusing. Without getting into all the reasons for this, I sincerely recommend following the 'get a new book' advice in the comments.

GDB Hanging - Not understanding why

I'm going through the book "The C Programming Language" and doing all of the examples plus poking around in GDB to see what's going on.
In the below example code, the goal is to evaluate a few lines of text to determine which is the longest line. I thought my own program was failing because gdb was hanging at the for loop which calls getchar(). I followed the backtrace, found the culprit function, but couldn't determine the exact problem. Then I did the same with the example code, and the exact same problem occurs at the for loop which calls getchar().
// file: ch1/ex16.c
// OBJECTIVE: Revise the main routine o the lnogest program
// so it will correctly print the length of arbitrarily long
// lines and as much as possible of the text.
#include <stdio.h>
#define MAXLINE 1000
int getLine(char line[], int maxline);
void copy(char to[], char from[]);
int main()
{
int len, max;
char line[MAXLINE], longest [MAXLINE];
max = 0;
while ((len = getLine(line, MAXLINE)) > 0) {
if (len > max) {
max = len;
copy(longest, line);
}
}
if (max > 0) {
printf("%s", longest);
}
return 0;
}
int getLine(char s[], int lim)
{
int c, 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;
}
void copy(char to[], char from[])
{
int i = 0;
while ((to[i] = from[i]) != '\0'){
++i;
}
}
Unlike when executing the program through the shell, gdb wouldn't accept ^d (ctrl+d) as EOF. Thanks to the comment that Duck provided above, I found that if I fed it a file through standard input gdb it solved the problem.
Ex:
(gdb) run < file.txt

Resources