I have looked at similar question on this site and googled why this is happening but have tried these solutionnot able to compile, difference between ncurses and curses, another compile error, but I am still having the problem with the error undefined reference to stdscr and wgetch the compiler is finding the library as far as I can figure out as I used find to locate the curses library and entered the full location in the #include line.
my code is as follows
#include <ncurses.h>
#include <stdio.h>
#include <string.h>
int first_line(char);
int main(){
char c = 0;
while((c = getch())!=EOF){
first_line(c);
}
return 0;
}
int first_line(char c){
if (c != '\n' && c != '\r'){
putchar(c);
do{
c = getch();
putchar(c);}
while( c !='\n');
}
else return 0;
return 0;
}
If you can point to what I've missed or am doing wrong I would much appreciate it.
ncurses.h is a header file (containing declarations), not a library (containing code that implements those declarations).
The error message you're seeing is from the linker, not from the compiler.
If you're using gcc, you need to add either -lcurses or -lncurses to the compiler command line (after your source file name).
For example, on my system I copied your source to c.c, and I can compile and link it using either
gcc c.c -o c -lcurses
or
gcc c.c -o c -lncurses
Related
I would like to use a library written in D for a C program compilable with MinGW GCC, for Windows. Here are the codes:
dll.d
extern (C) int dsquare(int n) nothrow
{
return n * n;
}
main.c
#include <stdio.h>
int main()
{
int res = dsquare(6); // Expect '36'
printf("res = %d\n", res);
return 0;
}
There is a tutorial on D's site, but it seems to target only Linux. Indeed, no explanation is given for creating such a dynamic D library for Windows and MinGW users.
D's documentation also says that the -shared option should generate a DLL version of the D code, but in my case, it generates an executable, I don't know why.
Also, anything that seems to generate files to be linked targets MVSC formats and nothing seems to be suitable for MinGW GCC compilers.
So, how can I generate a "GCC-friend" DLL with D, so that I can link it to my C program without having to use another compiler, such as GDC or LDC, via gcc main.c -o main -ldll -L. (I guess)?
I attached link with short explanation. Link D onto C is not so straightforward as C to D. Check D.org page here:
https://dlang.org/spec/betterc.html
Program:
#ifndef PRINTF_H
#define PRINTF_H
#include "my_put_char.h"
int my_printf(char *str, ...);
#endif
This is my Header file for my function.
#include <stdio.h>
#include "my_put_char.h"
void my_put_char(char c)
{
fwrite(&c, sizeof(char), 1, stdout);
}
This is my putchar implementation(my_put_char.c).
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "printf.h"
int my_printf(char *str, ...)
{
if(str == NULL)
return 0;
int i;
char a;
va_list print;
va_start(print,str);
for(i = 0; str[i] ; i++)
{
if(str[i] == '%')
{
i++;
switch(str[i])
{
case 'c':
a = va_arg(print, char);
my_put_char(a);
break;
}
}
}
va_end(print);
return 0;
}
At last, this is a part of my printf implementation.
I'm testing with %c to display a character.
When I do my_print("%c", 'd'); from main.c
it compiles and displays d.
But when I do my_print("%c", "hi"); , it still compiles and displays a number.
Question:
After(or before) writing a = va_arg(print, char); Is there a way to check whether my input is a different data type?
I'm trying to display an error if my input is a different data type.
I'm on this subject for 2 days and couldn't find any answer.
Thank you so much for your time!
when I do my_print("%c", "hi"); , it still compiles and displays a number
You've got some undefined behavior, so be scared. Your my_printf would call va_arg with an argument of the bad type (expected char promoted to int, got char*).
To explain what is happening you should dive into implementation details (look into the assembler code, e.g. with gcc -Wall -fverbose-asm -O -S; study your processor, its instruction set architecture, its application binary interface and calling conventions). You don't want to do that, it could take years and is not reproducible.
Read absolutely Lattner's blog on UB, right now!
Then download C11 specification n1570....
You could also, with gcc, use some function attributes. Don't forget to compile with all warnings and debug info (gcc -Wall -Wextra -g)
after writing a = va_arg(print, char); Is there a way to check whether my input is a different data type?
No, not really and not always. But the format function attribute could help. And you could also spend months customizing GCC with your own plugin or some GCC MELT extension (that is not worth your time). Be aware of the Halting Problem and Rice's Theorem (each makes static source code program analysis so challenging). Look also into source analyzing tools like Frama-C.
I'm implementing printf function
BTW studying the source code of existing free software implementations of the C standard library (such as GNU glibc and musl-libc) could be inspirational; they are based upon syscalls(2).
I was wondering how this works, creating a library and preloading it so a program can use it instead of the one in the include statement.
here is what I am doing and is not working so far .
//shared.cpp
int rand(){
return 33;
}
//prograndom.cpp
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){
srand(time(NULL));
int i = 10;
while(i--) printf("%d\n", rand()%100);
return 0;
}
Then in the terminal:
$ gcc -shared -fPIC shared.cpp -o libshared.so
$ gcc prograndom.cpp -o prograndom
$ export LD_PRELOAD=/home/bob/desarrollo/libshared.so
and finally
$ LD_PRELOAD=/home/bob/desarrollo/libshared.so ./prograndom
which doesnt print 33, just random numbers...
Your programs are C programs, but the cpp file extension implies C++, and GCC will interpret it that way.
That's an issue because it means that your function rand (in shared.cpp) will be compiled as a C++ function, with its name mangled to include its type-signature. However, in main you #include <stdlib.h>, which has the effect of declaring:
extern "C" int rand();
and that is the rand that the linker will look for. So your PRELOAD will have no effect.
If you change the name of the file from shared.cpp to shared.c, then it will work as expected.
Other alternatives, of dubious value, are:
Declare rand to be extern "C" in your shared.cpp file. You can then compile it as C++.
Force compilation as C by using the GCC option -x c.
I'm trying to get the ADC running on beaglebone black. The OS is Debian GNU/Linux 7.7. I'm using C language. When I try to compile the following code:
#include <stdio.h>
#include <unistd.h>
#include "pruio_c_wrapper.h"
#include "pruio_pins.h"
int main(int argc, const char *argv[]) {
PruIo *io = pruio_new(0, 0x98, 0, 1);
if (io->Errr) {
printf("Initialisation failed (%s)\n", io->Errr);
return 1;
}
if(pruio_config(io, 0, 0x1FE, 0, 4, 0)){
printf("Config failed (%s)\n", io->Errr);
return 1;
}
int a = 0;
int i;
while(1){
printf("\r%12o %12o %12o %12o %4X %4X %4X %4X %4X %4X %4X %4X\n", io->Gpio[0].Stat, io->Gpio[1].Stat, io->Gpio[2].Stat, io->Gpio[3].Stat, io->Value[1], io->Value[2], io->Value[3], io->Value[4], io->Value[5], io->Value[6], io->Value[7], io->Value[8]);
fflush(STDIN_FILENO);
usleep(1000);
}
pruio_destroy(io);
return 0;
}
But I get the following error:
undefined reference to 'pruio_new'
undefined reference to 'pruio_config'
I installed everything like FreeBasic compiler and pruss driver kit for freebasic and BBB and libpruio. I also copied all the header files in the same directory as the .c file, including "pruio_c_wrapper.h", "pruio-pins.h", "pruio.h" and all the other files in the src directory of libpruio. But it doesn't work.
Could you please tell me what to do?
Thanks
libfb is the FreeBASIC run-time library. When you want to compile against the old libpruio-0.0.x versions, you'll need an old FreeBASIC installation from
www{dot}freebasic-portal.de/dlfiles/452/bbb_fbc-0.0.2.tar.xz
Which installs /usr/local/lib/freebasic/libfb.so.
See the libpruio-0.0.x C example codes for compiler command line arguments (ie. header section of io_input.c).
But I recommend to use the new version libpruio-0.2 from (the last post links to the documentation of this new version)
http://www.freebasic-portal.de/dlfiles/592/libpruio-0.2.tar.bz2
which doesn't have this pitfalls, gcc compiles without FB installation, and provides new features like pinmuxing, PWM, CAP. There're small bugs in this versions C header, which is now named pruio.h: a missing enum and a copy / paste bug regarding a function name. See this thread for details:
http://www.freebasic.net/forum/viewtopic.php?f=14&t=22501
BR
Ok, I downloaded it, the binaries are in libpruio-0.0.2/libpruio/src/c_wrapper and so are the include files, copy the headers and libpruio.so to the same directory where the test.c file resides, and then
For the includes, you need to to append libpruio's include directory to the compiler command using -I. then you can do
#include <pruio_c_wrapper.h>
#include <pruio_pins.h>
You need to append the library to the linker command, with
-L. -lpruio
your complete compilation command will be then
gcc -o test -I. -L. -lpruio test.c
I have a bunch of C files and header files in the folder. When I compile the C files with MinGW compiler, it shows that there is no such file or directory. But I have all the files in the same folder. How do I get them to compile?
I have attached the code for your reference (file computil.c):
#include <stdio.h>
#include <computil.h>
#include <dataio.h>
int getc_skip_marker_segment(const unsigned short marker, unsigned char **cbufptr, unsigned char *ebufptr)
{
int ret;
unsigned short length;
ret = getc_ushort(&length, cbufptr, ebufptr);
if(ret)return(ret);
length -= 2;
if(((*cbufptr)+length) >= ebufptr)
{
fprintf(stderr, "ERROR : getc_skip_marker_segment : ");
fprintf(stderr, "unexpected end of buffer when parsing ");
fprintf(stderr, "marker %d segment of length %d\n", marker, length);
return(-2); }(*cbufptr) += length; return(0);
}
}
I am compiling it with gcc -c computil.c.
I believe you are going to have to add the current directory to the list of "standard places" that gcc uses. When you use instead of "computil.h", a Unix-style compiler won't look in the current directory.
For a quick fix to that, add -I. to the gcc command line. (dash, capital eye, period):
gcc -I. computil.c
If that's an application include file intended to be found where the source files are found, then you should change the include line to:
#include "computil.h"
That's one of the valuable nuances from Classic C that got lost in the ANSI standardization process. Standard C lets the compiler decide if there's a difference or between <> bracketed and "" quoted headers. It makes a difference in Unix and GNU ("GNU's Not Unix!"), well, pretty much is Unix only better in places.
To put it simple, #include <header.h> means "search in the compiler's own library directories, while #include "header.h means "search in the same directory as the .c file that made the #include".
I don't believe gcc has any library headers named computil.h and dataio.h, so the code won't compile.