I'm stuck with what seems a beginner's compilation error:
My simple program:
#include <stdlib.h>
#include <stdio.h>
#include "Tiles_Circular_Linked_List.h"
#define MAX_LINE_LENGTH 128;
int main(int argc, char **argv) {
struct node *head_tail;
FILE *file;
/*char filename[] = "/home/student/Desktop/Studies/C/testing_fodder/tiles";*/
argv++; /*go to second character-array argument*/
file = fopen(*argv, "r");
char *curr_line;
fgets(curr_line, MAX_LINE_LENGTH, file);
return 0;
}
I try to compile it using this command:
gcc -g -Wall -ansi launch_tiles.c -o tiles_prog
and get these errors:
launch_tiles.c: In function ‘main’:
launch_tiles.c:17:19: error: expected ‘)’ before ‘;’ token
launch_tiles.c:17:19: error: too few arguments to function ‘fgets’ /usr/include/stdio.h:628:14: note: declared here
launch_tiles.c:9:8: warning: variable ‘file’ set but not used [-Wunused-but-set-variable]
launch_tiles.c:8:15: warning: unused variable ‘head_tail’ [-Wunused-variable]
I am interested about the errors, not the warnings.
I can count three arguments that I pass to fgets and don't understand where do I miss parentheses so what's the problem?
Thanks!
change
#define MAX_LINE_LENGTH 128;
to
#define MAX_LINE_LENGTH 128
(without the ;). Easy mistake to make.
The C preprocessor does very simple, textual substitution, so with the wrongly-defined macro, you end up with
fgets(curr_line, 128;, file);
which is obviously a syntax error.
Related
This topic ought to have been flogged to death. I just spent 30 minutes locating what ended up being a missing semicolon at the end of a function prototype in a header file:
void foo(void);
void bar(void) // <<< Error on this line
void squee(void);
This is a common typo caused by copy-pasting the prototype from the C file. Of course according to the compiler the universe just fell apart, with an endless stream of absolutely nonsensical errors, none of them helpful.
This could be avoided by having an optional parsing phase to check for this condition in .h files then report a warning (promoted to error if settings mandate). This would require some restrictions on what you put in header files (no code, consistent format for prototypes, etc). But that's an easy compromise.
I can write my own SW tool to do this, but it would be more helpful to run it as a part of the build process. I use GCC in Eclipse. Any advice on where you'd start with this? Or anything pre-existing / off the shelf? Or perhaps just a better way to approach it?
Thank you.
it's far more common and more difficult to guess the following problem (in a header file):
struct something {
type1 var1;
type2 var2;
}
/* EOF */
and when you #include "header.h" into hello.c
#include <stdio.h>
#include "header.h"
int main(int argc, char **argv)
{
printf("Hello, world\n");
}
you get an error e.g.
lcu#europa:~$ gcc main.c
main.c:4:1: error: expected ';', identifier or '(' before 'int'
4 | int main(int argc, char **argv)
| ^~~
and the compiler has got out of header.h to signal the error in the line of main function. The thing can be worse if you happen to use legacy code and declare main() the old way:
main(argc, argv)
char **argv;
{
...
because then, the struct is a valid type and it is taken as the type returned by main() and you get (if you get it) the error far below (or no error at all, just a warning):
lcu#europa:~$ gcc main.c
main.c: In function 'main':
main.c:4:1: warning: type of 'argc' defaults to 'int' [-Wimplicit-int]
4 | main(argc, argv)
| ^~~~
In this case, the contents of main.c were:
#include <stdio.h>
#include "header.h"
main(argc, argv)
char **argv;
{
printf("Hello, world\n");
}
which is still valid c code.
(these examples were made by gcc, because clang ---the native compiler of freebsd--- detects the EOF in the header file and shows a warning stating that the type was not ended before the end of the include file. But this only happens if the type definition is the last of the file.
Note:
if you declare main as:
#include <stdio.h>
#include "header.h"
main(argc, argv)
int argc;
char **argv;
{
printf("Hello, world\n");
}
you get a complete compilation, without even a warning.
I've been given function called statPrint to handle printing of the system call stat(). The function is provided with another .o file. I'm getting errors when compiling my implementation with that function:
In function ‘main’:
statcall.c:9:19: error: expected expression before ‘,’ token
statPrint(argv[1]*,sb*);
^
statcall.c:9:19: error: incompatible type for argument 2 of ‘statPrint’
statcall.c:4:8: note: expected ‘struct stat *’ but argument is of type ‘struct stat’
extern statPrint(char*,struct stat*);
Here is my code:
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
extern statPrint(char∗,struct stat∗);
int main(int argc, char *argv[])
{
struct stat sb;
stat(argv[1],&sb); ///argv[1] contains input from the terminal/shell
statPrint(argv[1]*,sb*);
}
I compile it with(libstat contains the external function):
gcc -o statcall statcall.c libstat.o
How do I get rid of the errors?
This line makes no sense:
statPrint(argv[1]*,sb*);
There's no valid syntax that ends with *.
I think you want:
statPrint(argv[1], &sb);
Recommend you read up on addresses of variables and pointers.
Your function expects char * please provide it
statPrint(argv[1],sb);
I really didn't get what is argv[1]*
This is my header file, tree.h
#ifndef TREE_H_
#define TREE_H_
#if defined treeItem
extern int totalnode;
treeItem *addItem(treeItem *node, char *w);
void printInOrder(treeItem *node, FILE *output);
void freeTree(treeItem *node);
#endif
#endif
This is the main() in main.c which include tree.h
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "tree.h"
#define MAX 1024
extern int totalnode;
int main(int argc, char *argv[]){
FILE *input;
FILE *output;
char *filename;
char ch[MAX];
//extern int totalnode;
struct treeItem *element;
element = NULL;
int i;
if (argc > 2){
output = fopen(argv[1], "w");
for(i = 2; i < argc + 1; i++){
filename = argv[i];
input = fopen(filename, "r");
if(input != NULL){
while(getword(ch, MAX, input) != EOF)
if (isalpha(ch[0]))
element = addItem(element, ch);
}
}
printInOrder(element, output);
fprintf(output,"-------------- \n ");
fprintf(output,"%4d Total number of different words",totalnode);
freeTree(element);
fclose(input);
fclose(output);
}
else{
printf("There is no input file.\n");
}
return 0;
}
compiler says:
../main.c: In function 'main':
../main.c:57: warning: implicit declaration of function 'addItem'
../main.c:57: warning: assignment makes pointer from integer without a cast
../main.c:60: warning: implicit declaration of function 'printInOrder'
../main.c:64: warning: implicit declaration of function 'freeTree'
another error: Undefined symbols for architecture x86_64:
"_totalnode", referenced from:
_main in main.o
_addItem in tree.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
If I put all code in the same .c file without using header file, it works. But for now, it doesn't work. How can I fix it?
The line
#if defined treeItem
and the matching #endif should be removed from tree.h
Remember that preprocessing occurs conceptually before (or as the very first step of) the real compilation.
In general, you could have obtained the preprocessed form of main.c with
gcc -C -E main.c > main.i
and then look (e.g. with a pager like less) inside main.i
I often remove the generated preprocessor directives with
gcc -C -E main.c | grep -v '^#' > main.i
gcc -Wall -c main.i
this gives error messages with line numbers referring inside main.i (not main.c or tree.h) which is sometimes useful to debug macros. Another useful option to gcc is -H: it shows every #include-d file
In order to use the tree.h file 'as-is', and have it define items as you expect, you will have to define treeItem:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
/* You will need to define 'treeItem' prior to including 'tree.h'. */
typedef /* the defintition here */ treeItem;
#include "tree.h"
#define MAX 1024
extern int totalnode;
If you have the liberty of editing the tree.h file, it would probably be better to remove the line:
#if defined treeItem
and one of the lines:
#endif
Because you have pre compiler directives which exclude the substantive body of tree.h unless treeItem is defined, you must #define treeItem prior to the inclusion of tree.h within main.c, this is due to the way that precompiler directives are processed. This will solve the immediate problem.
I see that in main.c you have the line: struct treeItem *element;
If I am interpreting correctly that you intended this to satisfy the #ifdef treeItem line in your header, then you are misunderstanding how these # lines are like a separate language to C/C++. These lines are called precompiler directives, or more casually macros. Macros are commands for the preprocesser which operates over text files prior to compilation, for the purposes of creating in memory a full source code that can be compiled into an object that can later be linked with others to form your program. The preprocessor's defines are different from definitions in C/C++, and they don't directly interact. This line about the struct is practically invisible to the preprocessor, it knows nothing about C/C++. You must define this treeItem using #define, prior to the #ifdef.
More aesthetically, your header file should not guard like this, because it is superfluous. The main.c module's #include "tree.h" line alone is enough to indicate the intention of including the substantive body of tree.h. You have an appropriate guard against repeated inclusions, but the second guard regarding the treeItem definition seems unnecessary and is the cause of this issue. This latter paragraph is simply reiterating what other's have said, and would be technically superfluous as well if it does not contribute to persuading you of this opinion, however avoiding hypocrisy the first paragraph is a solution to your issue that does not intrude on your decision regarding said opinion.
The following is my file named crack.c:
#include <stdio.h>
#define _XOPEN_SOURCE
#include <unistd.h>
void execute(char *alpha)
{
char *beta = crypt(alpha);
printf("%s", beta);
}
int main(int argc, string argv[]){
....
execute(argv[1]);
else{
printf("You submitted %d command line arguments. That's an issue. You need to submit exactly one.", argc);
return 1;
}
}
The following is what I type into the command line:
jharvard#appliance (~/Dropbox/hacker2): clang -o crack -lcrypt crack.c
The following is what the command line spits back out at me:
crack.c:8:19: warning: implicit declaration of function 'crypt' is
invalid in
C99 [-Wimplicit-function-declaration]
string beta = crypt(alpha);
^ crack.c:8:12: warning: incompatible integer to pointer conversion initializing
'string' (aka 'char *') with an expression of type 'int'
[-Wint-conversion]
string beta = crypt(alpha);
^ ~~~~~~~~~~~~ 2 warnings generated.
Anyone know what's going on?
I had the same problem, and I realized that changing the header
#define _XOPEN_SOURCE
#include <unistd.h>
by
#define _GNU_SOURCE
#include <crypt.h>
makes disapear the error in compilation time
The function signature of crypt is:
char * crypt (const char *key, const char *salt)
It seems that you forgot one parameter! So your line:
string beta = crypt(alpha);
Should be something like that:
string beta = crypt(alpha, salt);
Make sure you have the define and include for crypt as the very first lines at the top of your file before any other includes.
#define _XOPEN_SOURCE
#include <unistd.h>
I'm getting back into c after a long hiatus. Here's a little program I've written to output a files size. It compiles, and it works correctly, and it's pretty much copied and pasted from the man page. But it gives me an annoying warning from gcc.
gcc -ggdb read_file_to_char_array.c -o read_file_to_char_array `mysql_config --cflags --libs && pkg-config --cflags --libs gtk+-2.0 && pkg-config --cflags --libs sdl`
read_file_to_char_array.c: In function ‘main’:
read_file_to_char_array.c:22:19: warning: [enabled by default]
/usr/include/i386-linux-gnu/sys/stat.h:216:12: note: expected ‘int’ but argument is of type ‘struct FILE *’`
Any hints as to how I can make it go away (without disabling warnings ;) )
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv) {
unsigned long *lengths;
FILE *fp;
struct stat sb;
fp = fopen("image.png", "rb");
fstat(fp,&sb);
printf(" Size - %lld : ", (long long)sb.st_size);
fclose(fp);
}
You need to pass a file descriptor, not a FILE *.
int fstat(int fildes, struct stat *buf);
Try using fileno(3) to get the file descriptor from a FILE *.
int fd;
fp = fopen("image.png", "rb");
fd = fileno(fp);
fstat(fd, &sb);