I believe I copied this code verbatim from the book. It works, but generates three warnings:
C4047: 'function' : 'char' differs in levels of indirection from 'char [1000]'
C4024: 'copy' : different types for formal and actual parameter 2
C4028: formal parameter 2 different from declaration
Here is the code. What am I doing wrong? Many thanks.
#include <stdio.h>
#define MAXLINE 1000 //max input line size
int getline(char line[], int maxline);
void copy(char to[], char from);
//print longest input line
main()
{
int len; //current line length
int max; //max 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;
}
The problem is that in the forward declaration on the fifth line you have this:
void copy(char to[], char from); // <<== No square brackets
and in the definition you have this:
void copy(char to[], char from[]) ...
The definition is correct; the forward declaration is not. You need to add square brackets to forward declaration to fix this problem.
Related
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.
I'm learning C with "The C programming language" book. And I'm stucked with this error.
Here is the code:
#include <stdio.h>
#define MAXLINE 1000 // Max input line length
int getline(char line[], int maxline);
void copy(char to[], char from[]);
// Printing the longest input line
int main()
{
int len; // Current line length, max line length ever seen
int max;
char line[MAXLINE];
char longest[MAXLINE];
max = 0;
while((len = getline(line, MAXLINE)) > 0)
{
if(len > max) // If current line length > previous max length - rewrite.
{
max = len;
copy(longest, line);
}
}
if(max > 0) // If there was a line
printf("%s", longest);
return 0;
}
int getline(char s[],int lim) // return length of line
{
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;
}
This code is an example from the book :)
Trying to compile it on Linux: Linux 5.4.97-gentoo.
GCC version: 10.2.0.
getline is already declared in <stdio.h>. Change the method name to my_getline.
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.
As I am going through a sample code in the book (program that reads a set of text lines and prints the longest) :
#include <stdio.h>
#define MAXLINE 1000
int getline(char line[], int maxline);
void copy(char to[], char from[]);
main()
{
int len;
int max;
char line[MAXLINE];
char 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;
i = 0;
while ((to[i] = from[i]) != '\0')
++i;
}
gcc spits out
longestline.c:4:5: error: conflicting types for ‘getline’
4 | int getline(char line[], int maxline);
| ^~~~~~~
In file included from longestline.c:1:
/usr/include/stdio.h:616:18: note: previous declaration of ‘getline’ was here
616 | extern __ssize_t getline (char **__restrict __lineptr,
| ^~~~~~~
longestline.c:7:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
7 | main()
| ^~~~
longestline.c:25:5: error: conflicting types for ‘getline’
25 | int getline(char s[], int lim)
| ^~~~~~~
In file included from longestline.c:1:
/usr/include/stdio.h:616:18: note: previous declaration of ‘getline’ was here
616 | extern __ssize_t getline (char **__restrict __lineptr,
| ^~~~~~~
that is the exact sample from the book, so what can be done here? I think this might be due to this book being quite outdated, what is the solution?
The problem is that there is a POSIX function called getline. Your compiler is defaulting to POSIX compatibility instead of ISO C compatibility. To work around it you can either:
Call your function something else, or
Invoke the compiler in ISO C mode.
For gcc use a switch such as -std=c11 ; or it is also possible to control dialect on a per-file basis with feature test macros.
It turns out getline is defined in stdio.h, simply renamed the function:
int gettline(char line[], int maxline);
int getline(char s[], int lim)
.
#include <stdio.h>
#define MAXLINE 1000
int gettline(char line[], int maxline);
void copy(char to[], char from[]);
main()
{
int len;
int max;
char line[MAXLINE];
char longest[MAXLINE];
max = 0;
while ((len = gettline(line, MAXLINE)) > 0)
if (len > max){
max = len;
copy(longest, line);
}
if (max > 0)
printf("%s", longest);
return 0;
}
int gettline(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;
}
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?