i am reading the C program book written by Denis and i was practicing his examples. I tried this example on my own and then copy pasted the same example from book. I get the followin error.
Code :
#include <stdio.h>
#define MAXLINE 1000 /* maximum 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; /* maximum 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;
}
Error:
ex16.c:4:5: error: conflicting types for 'getline'
int getline(char line[], int maxline);
^
/usr/include/stdio.h:440:9: note: previous declaration is here
ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict) __OSX_AVAILABLE_...
^
ex16.c:8:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
main()
^~~~
ex16.c:16:40: error: too few arguments to function call, expected 3, have 2
while ((len = getline(line, MAXLINE)) > 0)
~~~~~~~ ^
/usr/include/stdio.h:440:1: note: 'getline' declared here
ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict) __OSX_AVAILABLE_...
^
ex16.c:27:5: error: conflicting types for 'getline'
int getline(char s[], int lim)
^
/usr/include/stdio.h:440:9: note: previous declaration is here
ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict) __OSX_AVAILABLE_...
^
1 warning and 3 errors generated.
I am using function prototype correctly only i guess. Refered other internet sources also. I am not sure if its because of compiler. I am using Gcc version 4.3 i guess. OS - mac maverics.
Can you please help me ?
Thanks.
Just call your function getlineMy() in the places where you declare, define and use it.
getline() is already declared in stdio.h (link) and its implementation will be linked to your program so you cannot use that name unless you do tricks.
You have to set GCC to compile your code as C.
gcc -std=c99 -pedantic-errors -Wall
You will then get one error:
8:1: error: return type defaults to 'int'
This is because you are using the wrong definition for main(). Correct it to int main().
The name getline is just fine to use, there is no such function in stdio.h and the compiler is not allowed to add functions that are non-standard extensions inside that header, without naming them with a _ prefix.
Related
This is a simple program which generates MD5 digest of a file and compares with the predefined MD5 digest in a program and checks for its integrity.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include <openssl/md5.h>
char * calculate_file_md5(const char *filename)
{
unsigned char c[MD5_DIGEST_LENGTH];
int i;
MD5_CTX mdContext;
int bytes;
unsigned char data[1024];
char *filemd5 = (char*) malloc(33 *sizeof(char));
FILE *inFile = fopen (filename, "rb");
if (inFile == NULL) {
perror(filename);
return 0;
}
MD5_Init (&mdContext);
while ((bytes = fread (data, 1, 1024, inFile)) != 0)
MD5_Update (&mdContext, data, bytes);
MD5_Final (c,&mdContext);
for(i = 0; i < MD5_DIGEST_LENGTH; i++) {
sprintf(&filemd5[i*2], "%02x", (unsigned int)c[i]);
}
printf("calculated md5:%s ", filemd5);
printf (" %s\n", filename);
fclose (inFile);
return filemd5;
}
int main(int argc, char **argv) {
char * predefined_md5 = "8e2745d333daa9666a8bbebcd32a39bb";
char *new_md5 = calculate_file_md5("backup.json");
if (!strcmp(predefined_md5, new_md5)) {
printf("md5 matched\n");
} else {
printf("md5 not matched\n");
}
free(new_md5);
return 0;
}
Program compiled and run gracefully but can any one tell me to sort the following warnings
GenerateMD5Hash.c: In function ‘calculate_file_md5’:
GenerateMD5Hash.c:18:9: warning: ‘MD5_Init’ is deprecated: Since OpenSSL 3.0 [-Wdeprecated-declarations]
18 | MD5_Init (&mdContext);
| ^~~~~~~~
In file included from headers.h:5,
from GenerateMD5Hash.c:1:
/usr/include/openssl/md5.h:49:27: note: declared here
49 | OSSL_DEPRECATEDIN_3_0 int MD5_Init(MD5_CTX *c);
| ^~~~~~~~
GenerateMD5Hash.c:22:9: warning: ‘MD5_Update’ is deprecated: Since OpenSSL 3.0 [-Wdeprecated-declarations]
22 | MD5_Update (&mdContext, data, bytes);
| ^~~~~~~~~~
In file included from headers.h:5,
from GenerateMD5Hash.c:1:
/usr/include/openssl/md5.h:50:27: note: declared here
50 | OSSL_DEPRECATEDIN_3_0 int MD5_Update(MD5_CTX *c, const void *data, size_t len);
| ^~~~~~~~~~
GenerateMD5Hash.c:24:9: warning: ‘MD5_Final’ is deprecated: Since OpenSSL 3.0 [-Wdeprecated-declarations]
24 | MD5_Final (c,&mdContext);
| ^~~~~~~~~
In file included from headers.h:5,
from GenerateMD5Hash.c:1:
/usr/include/openssl/md5.h:51:27: note: declared here
51 | OSSL_DEPRECATEDIN_3_0 int MD5_Final(unsigned char *md, MD5_CTX *c);
using ubuntu mate OS
command used to compile
gcc GenerateMD5Hash.c -lcrypto -o GenerateMD5Hash
From OpenSSL:
The following functions have been deprecated since OpenSSL 3.0, and
can be hidden entirely by defining OPENSSL_API_COMPAT with a suitable
version value, see openssl_user_macros(7):
unsigned char *MD5(const unsigned char *d, unsigned long n, unsigned char *md);
int MD5_Init(MD5_CTX *c);
int MD5_Update(MD5_CTX *c, const void *data, unsigned long len);
int MD5_Final(unsigned char *md, MD5_CTX *c);
All of the functions described on this page are deprecated.
Applications should instead use
EVP_DigestInit_ex(3),
EVP_DigestUpdate(3) and
EVP_DigestFinal_ex(3).
They are there for backwards compatibility. If you wish to ignore the warnings, you could:
Just ignore them.
Redirect the output to /dev/null.
Use the functions they recommend instead.
Reading Kernigan, and the given code doesn't seem to work because of 'conflicting types' error for the user function.
The compiler I'm using is cc 7.4.0. I've declared the function in the beginning and have been checking and re-checking the types seemingly forever. Guess I'm missing something.
#include <stdio.h>
#define MAXLINE 1000
int getline(char line[], int maxline);
main()
{
int len;
char line[MAXLINE];
while((len = getline(line, MAXLINE)) > 0)
;
return 0;
}
int getline(char s[], int lim)
{
int i, c;
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;
}
The error I'm getting is
func.c:4:5: error: conflicting types for ‘getline’
int getline(char line[], int maxline);
^~~~~~~
In file included from func.c:1:0:
/usr/include/stdio.h:616:20: note: previous declaration of ‘getline’ was here
extern _IO_ssize_t getline (char **__restrict __lineptr,
^~~~~~~
^~~~
func.c:25:5: error: conflicting types for ‘getline’
int getline(char s[], int lim)
^~~~~~~
In file included from func.c:1:0:
/usr/include/stdio.h:616:20: note: previous declaration of ‘getline’ was here
extern _IO_ssize_t getline (char **__restrict __lineptr,
getline is already declared (in error actually) in <stdio.h> and its signature differs from yours.
The simplest thing to do is to rename your version to something different.
You need to block the compiler from spewing non-standard crap into standard headers. You are using some compiler which has defined a non-standard getline function inside the standard library header stdio.h, which is non-conforming.
With gcc you should compile as for example gcc -std=c17 -pedantic-errors to prevent this from happening.
In K&R Chapter 1.9, I've been experimenting with the program provided below. Particularly, what would happen if I removed certain decelerations of functions.
So, I removed line #4. int getline(char line[], int maxline
And the program complies perfectly and functions properly as far as I'm aware.
When I remove line #5. void copy(char to[], char from[]);
The program throws the following error:
yay.c:37:6: warning: conflicting types for ‘copy’
void copy(char to[], char from[])
yay.c:15:9: note: previous implicit declaration of ‘copy’ was here
copy(longest, line);
#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 = getfatline(line, MAXLINE)) > 0)
if (len > max) {
max = len;
copy(longest, line);
}
if (max > 0)
printf("%s", longest);
return 0;
}
int getfatline(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;
}
Could anyone explain this to me?
As per the latest C standard C11, every function has to be (at least) declared before it has been used. In that way, compiler will have the knowledge of the function signature.
In the code, while calling a function, if the declaration (at least) is not visible to the compiler, (due to some legacy reason), the compiler (used to) assume
The function returns an int
accepts any number of paramater.
Later, when you define the function to have a return type other than int, it will create the conflict.
That is why,
removing the forward declaration of getline() produces no error.
removing the forward declaration of copy() produces the error, mismatch in the return type.
Along the same line, main() is no longer required to be supported, as implicit int has also been removed. You should write int main(void), at least to be standard conforming.
To add a function you need to give a prototype for it. Thats what this is
void copy(char to[], char from[]);
But if you don't provide the prototype, the return type of the function is taken as int by default.
This is the reason why it is working for the function getfatline(), because its return type is int when you are using it later in the code, which is the same as taken by default when you remove the prototype.
But when you remove the prototype for the function copy, the return type is set to int by default but your function definition has the return type as void, that is where the conflict is occurring, and it is throwing an error.
Getline is actually defined in in the stdio.h header
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
hence deleting your own getline implementation will not throw an error. Instead, deleting your other function, will throw an error because no such function does exist in stdio.h but it's user-defined. By the way, in this case the problem you are facing can be simply resolved by deleting the function itself from the program.
I'm studying C with K&R book. There is an exercise, here it is: "Write a program to print all input lines that are longer than 80 characters". So I wrote this code:
#include <stdio.h>
#include <stdlib.h>
int getline(char s[], int lim);
#define MINLINE 80
#define MAXLINE 1000
/*
*
*/
int main(int argc, char** argv) {
int len; //current line length
char line[MAXLINE]; //current input line
int proceed=0;
while((len=getline(line, MAXLINE))>0)
if(line[len-1]!='\n'){
printf("%s", line);
proceed=1;}
else if(proceed==1){
printf("%s", line);
proceed=0;}
else if(len>MINLINE){
printf("%s", line);
}
return 0;
}
int getline(char s[], int lim){
int i, c;
for(i=0; i<lim-1 && (c=getline())!='*' && c!='\n'; i++){
s[i]=c;
}
if(c=='\n'){
if(i<=lim-1){
s[i]=c;}
i++;}
s[i]='\0';
return i;
}
I can't compile it and I have no idea how to fix it. Could you help me?
This is the error message:
main.c:11:5: error: conflicting types for ‘getline’
In file included from /usr/include/stdio.h:62:0,
from main.c:8:
/usr/include/sys/stdio.h:37:9: note: previous declaration of ‘getline’ was here
main.c:38:5: error: conflicting types for ‘getline’
In file included from /usr/include/stdio.h:62:0,
from main.c:8:
/usr/include/sys/stdio.h:37:9: note: previous declaration of ‘getline’ was here
main.c: In function ‘getline’:
main.c:40:5: error: too few arguments to function ‘getline’
main.c:38:5: note: declared here
make[2]: *** [build/Debug/Cygwin_4.x_1-Windows/main.o] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
getline() function is already declared in stdio.h header file.if you want to redefine it in your file. just modify as my_getline()
In this for loop you need to use getchar() not getline()
for(i=0; i<lim-1 && (c=getline())!='*' && c!='\n'; i++)
for(i=0; i<lim-1 && (c=getchar())!='*' && c!='\n'; i++)
You need to use pointer in your function to get the input into line.other wise s is become local to the function.
int my_getline(char *, int); //declaration
int my_getline(char *s, int lim) //defination
{
//....
}
function call is same
len= my_getline(line, MAXLINE)
Finally use some conditional mechanism to get out of while loop in the main.
The function getline is already declared in stdio.h. Rename your function to something else.
getline is a function of the C standard library defined in stdio.h. The compiler want to use that version instead of yours.
Rename your function, for instance into my_getline and you should be fine.
Change the function name, getline exists already
I'm working through K&R, using Clang as my compiler.
Exercise 1-16 produces the "conflicting types for 'getline'" error when compiled with Clang. I'm guessing because one of the default libraries has a getline function.
What options should I pass to Clang when compiling K&R exercises so as to avoid anything else being included?
The exercise sample to be modified is:
#include <stdio.h>
#define MAXLINE 1000
int getline(char line[], int maxline);
void copy(char to[], char from[]);
/* print longest input line */
main()
{
int len; /* current line length */
int max; /* maximum line 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); /* line -> longest */
}
if (max > 0) /* there was a line */
printf("\n\nLength: %d\nString: %s", max -1, 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 errors from Clang when invoked as: cc ex1-16.c -o ex1-16
ex1-16.c:4:5: error: conflicting types for 'getline'
int getline(char line[], int maxline);
^
/usr/include/stdio.h:449:9: note: previous declaration is here
ssize_t getline(char ** __restrict, size_t * __restrict, FILE *...
^
ex1-16.c:17:38: error: too few arguments to function call, expected 3, have 2
while ((len = getline(line, MAXLINE)) > 0)
~~~~~~~ ^
/usr/include/stdio.h:449:1: note: 'getline' declared here
ssize_t getline(char ** __restrict, size_t * __restrict, FILE *...
^
ex1-16.c:29:5: error: conflicting types for 'getline'
int getline(char s[], int lim)
^
/usr/include/stdio.h:449:9: note: previous declaration is here
ssize_t getline(char ** __restrict, size_t * __restrict, FILE *...
^
3 errors generated.
The problem is just that your system already provides a function called getline. man getline should tell you its signature. On my system it's:
ssize_t getline(char ** restrict linep, size_t * restrict linecapp, FILE * restrict stream);
You can either match that or just rename your function to be called 'mygetline' or something like that.
Alternately, if you can avoid including stdio.h, you can avoid the problem entirely.
As to your final question:
What options should I pass to Clang when compiling K&R exercises so as to avoid anything else being included?
You can't - the system headers are what they are, and have presumably moved on since K&R was last revised in 1988. There have been multiple C standard updates since then. In some ways K&R is really starting to get long in the tooth.
Here is a similar question: Why do I get a "conflicting types for getline" error when compiling the longest line example in chapter 1 of K&R2?
It's the same issue but with gcc. A solution is to put the compiler into ANSI C mode, which disables GNU/POSIX extensions.
Try the following:
$ clang test.c -ansi
or alternatively
$ clang test.c -std=c89
Tested sucessfully on my machine:
$ clang --version
clang version 3.3 (tags/RELEASE_33/rc2)
Target: x86_64-redhat-linux-gnu
Thread model: posix
With this compiler on a machine at my university it was not even required to specify the ANSI mode for successful compilation:
->clang --version
Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
Target: x86_64-apple-darwin10
Thread model: posix