I'm trying to populate a global int variable by passing command line arguments to a function. When I do this, I get warnings (see below), as well as a funky return number (such as 52 instead of the expected 49).
Any hints would be greatly appreciated. This is HW - but only a very small portion of the overall assignment.
#include <stdio.h>
#include <stdlib.h>
#include "kangarooHeaders.h"
int numJoeys = MIN_NUM_LEGAL_JOEYS - 1;
int main (int argc, char* argv[])
{
initializeNumJoeys(argc,argv);
printf("%d", numJoeys);
}
void initializeNumJoeys(void argc, void *argv[])
{
char line[LINE_LEN];
if (argc > MAMAS_NUM_JOEYS_CMD_LINE_INDEX)
numJoeys = *argv[1];
}
argv_test.c:13: warning: conflicting types for ‘initializeNumJoeys’
argv_test.c:9: warning: previous implicit declaration of ‘initializeNumJoeys’ was here
Put this above the main() function
void initializeNumJoeys(int argc, char *argv[]);
the reason is implicit function declaration, the compiler doesn't find a prototype for initializeNumJoeys() and implicitly declares it as
int initializeNumJoeys();
so when it finds the definition, then it's conflicting with the previous declaration.
Also, change this
numJoeys = *argv[1];
to
numJoeys = strtol(argv[1], NULL, 10);
and also, the function signature is wrong
void initializeNumJoeys(void argc, void *argv[])
/* ^ should be int */
so change it to
void initializeNumJoeys(int argc, void *argv[])
don't forget to fix the prototype.
Related
Summary
I am trying to pass the text that user has put in the terminal and pass it to the function named printString(). I don't fully understand C but I think I has to do with the pointer not being in the heap. Any help would be appreacitaed!
#include <stdio.h>
void printString();
int main (int argc, char* argv[]) {
int commandAmount = 1;
while (commandAmount < argc) {
printString(commandAmount, &argv);
}
return 0;
}
void printString(int commandAmount, char* argv[]) {
printf("the word is %s," , argv[commandAmount]);
}
./shortExample example
Segmentation fault (core dumped)
The prototype void printString(); does not match the actual implementation.
It should have been:
void printString(int commandAmount, char* argv[]);
You could also skip the prototype and just implement the function before main. Your loop while (commandAmount < argc) seems to not have any way to finish since you never increase commandAmount. This can cause undefined behavior and with such, your program may crash or do just about anything.
I suggest making a for-loop to fix that.
Example:
#include <stdio.h>
void printString(int commandAmount, char* argv[]) {
printf("the word is %s,", argv[commandAmount]);
}
int main(int argc, char* argv[]) {
for(int commandAmount = 1; commandAmount < argc; ++commandAmount) {
printString(commandAmount, argv);
}
}
or in the way you structured it:
#include <stdio.h>
void printString(int commandAmount, char* argv[]); // corrected
int main(int argc, char* argv[]) {
int commandAmount = 1;
while (commandAmount < argc) {
printString(commandAmount, argv);
++commandAmount; // needed
}
}
void printString(int commandAmount, char* argv[]) {
printf("the word is %s,", argv[commandAmount]);
}
For starters this function declaration
void printString();
does not provide a function prototype. So the compiler determines the type of the parameters of the function from the function call
printString(commandAmount, &argv);
However the expression &argv used in this call
printString(commandAmount, &argv);
has the type char *** due to the declaration of the identifier argv
int main (int argc, char* argv[]) {
^^^^^^^^^^^^
But the corresponding parameter in the definition of the function printString has the type char ** due to adjusting by the compiler parameters having array types to pointers to array element type.
That is this function declaration
void printString(int commandAmount, char* argv[]) {
is adjusted by the compiler to
void printString(int commandAmount, char** argv) {
^^^^^^^^^^^
Thus there are incompatible types of the argument expression and of the parameter. As a result this call
printf("the word is %s," , argv[commandAmount]);
invokes undefined behavior.
Moreover this loop in main
int commandAmount = 1;
while (commandAmount < argc) {
printString(commandAmount, &argv);
}
in general is an infinite loop because the variable commandAmount is not changed within the loop.
Firstly you should provide the function prototype before main to make your program more safer
void printString(int commandAmount, char** argv);
and call the function like
printString(commandAmount, argv);
^^^^
Of course you need also to change the loop in main.
Pay attention to that as the value of the parameter commandAmount is not outputted within the function then in fact it is redundant. You could pass to the function the pointer to the string itself. For example
#include <stdio.h>
void printString( const char *s );
int main( int argc, char* argv[] )
{
for ( int commandAmount = 1; commandAmount < argc; commandAmount++ )
{
printString( argv[commandAmount] );
}
putchar( '\n' );
return 0;
}
void printString( const char *s )
{
printf( "the word is %s, " , s );
}
I am using clang on linux.
What is the correct way to format this block?
(int ^(int, char**)) (^f2b)(int, char**) = (int ^(int, char**)) ((int (*func)(int, char**)))
{
return int ^(int argc, char** argv){ func(argc, argv)};
};
I am getting an error
error: type-id cannot have a name
int (^f2b)(int, char**) = (int ^(int, char**)) ((int (*func)(int, char**)))
The error underlines (*func).
I am trying to create a block that takes in a function pointer named func as a parameter and returns a block that calls that func using the arguments it is passed.
The key is the Block_copy function from <Block.h>1. That puts a copy of a block on the heap, which allows the block to be returned.
#include <stdio.h>
#include <Block.h>
typedef int (^block_t)(int, char **);
typedef int (*func_t)(int, char **);
block_t (^createBlock)(func_t func) = ^(func_t func)
{
return Block_copy( ^(int argc, char **argv) { return func(argc, argv); } );
};
int showFirst(int argc, char *argv[])
{
printf("%s\n", argv[0]);
return argc;
}
int main(void)
{
int argc = 3;
char *argv[] = {"hello", "world", NULL};
block_t block1 = createBlock(showFirst);
int count = block1(argc, argv);
printf("count=%d\n", count);
Block_release(block1);
}
createBlock takes a function pointer as its argument, and returns a block with the signature int (^block)(int, char **).
showFirst is just one possible implementation of the function that can be passed to createBlock. It displays the first string in the argv array and returns the value in argc.
The main function creates a block from the showfirst function. It then invokes the block, prints the returned value, and releases the block.
The output from the code is:
hello
count=3
1 I was not aware of <Block.h> until reading OP's answer.
http://thirdcog.eu/pwcblocks/ helped a lot.
#include <stdlib.h>
#include <stdio.h>
#include <Block.h>
int fake_main(int argc, char** words)
{
printf("%s\n", (char*)words);
return argc;
}
int main(int argc, char* argv[])
{
typedef int(*main_type_func)(int, char**);
typedef int(^main_type)(int, char**);
typedef main_type(^f2b_type)(main_type_func);
f2b_type f2b = ^ (main_type_func func)
{
return Block_copy(^ (int apple, char** ban)
{
return func(apple, ban);
});
};
printf("%d\n", f2b(fake_main)(1, "words worked"));
}
This is a minimum example of accomplishing the goals I outlined in the question.
The trick is the typedefs. Simplify the type signature by creating typedefs to help. I recommend that you use these whenever you want to accept and/or return a function pointer/block pointer.
Block_copy() moves the block from the stack into the heap.
It would be more correct to save the block pointer returned from
f2b(fake_main)
Then after use call
Block_release()
On it.
Your type syntax is incorrect. Based on your usage, I'm guessing you are declaring f2b to be a pointer to a block, which takes a pointer to a function that takes an int and a char ** and returns an int, and the block returns another block that takes an int and a char ** and returns an int.
The proper syntax for that declaration would be:
int (^(^f2b)(int (*) (int, char **)))(int, char **)
The syntax for more complicated C types is often counter-intuitive, especially in cases of multiple levels of functions and arrays.
The ever-useful cdecl.org website supports blocks: declare f2b as block(pointer to function(int, pointer to pointer to char) returning int) returning block(int, pointer to pointer to char) returning int (they say "block" whereas I say "pointer to block")
Your block definition written out using full block literal syntax (including return types) would be something like this (remembering to copy the block in order to return it):
int (^(^f2b)(int (*) (int, char **)))(int, char **) =
^int (^(int (*func)(int, char **)))(int, char **) {
return Block_copy(^int (int argc, char **argv) {
return func(argc, argv);
});
};
Return types may be omitted in block literals, so it could be written like:
int (^(^f2b)(int (*) (int, char **)))(int, char **) =
^(int (*func)(int, char **)) {
return Block_copy(^(int argc, char **argv) {
return func(argc, argv);
});
};
I'm new to C and wrote the following code that returns a char.
int main(int argc, char * argv[]){
char c = test();
printf("num = %c \n", c);
}
char test(){
char c = 'z';
return c;
}
But I get the following error when compiling:
read.c:8:1: warning: data definition has no type or storage class [enabled by default]
test();
^
read.c:71:6: error: conflicting types for ‘test’
char test(){
^
read.c:8:1: note: previous declaration of ‘test’ was here
test();
^
Any ideas? Does this require memory allocation? If so, why?
It is because you either have to define the function prototype above the main, or move the function above the main.
char test();
int main(int argc, char * argv[]){
char c = test();
printf("num = %c \n", c);
}
char test(){
char c = 'z';
return c;
}
or
char test(){
char c = 'z';
return c;
}
int main(int argc, char * argv[]){
char c = test();
printf("num = %c \n", c);
}
You haven't provided a prototype for test() function by the time you call it in main(). Either do char test(void); at the top of your source file (or more conventionally in a header file).
Other option is to move the definition of test() above main() function which would the ensure the definition itself provides the prototype.
The reason for the error:
error: conflicting types for ‘test’
is that in pre-C99 C, compiler implicitly provides an int returning prototype for test() (known as implicit int rule) which conflicts with the actual definition of test() (where it actually has char as return type). Note that this is no longer valid (in C99 and later).
In C the compiler start "reading" the code from the top to the bottom, so when it's on your main function trying to figure out what is test() it don't know this function yet.
To solve it you can put your main funcion after the test() function, or use function prototype wich is better code practice, manly for future readings of the code. Like this:
char test();
int main(int argc, char * argv[]){
char c = test();
printf("num = %c \n", c);
}
char test(){
char c = 'z';
return c;
}
Before using the name test in this statement
char c = test();
it must be declared.
And this message
read.c:8:1: warning: data definition has no type or storage class [enabled by default]
test();
^
says that the compiler does not know the type of the expression test() used in the declaration of the variable c as an initializer.
For compatibility with old versions of the C Standard the compiler assumes that the function has the return type int. However then it encounters that the function has the return type char. And these compiler messages say about this
read.c:71:6: error: conflicting types for ‘test’
char test(){
^
read.c:8:1: note: previous declaration of ‘test’ was here
test();
^
So before using the function you have to declare it
char test( void );
Pay attention to that the parameters of the function main
int main(int argc, char * argv[]){
are not used. So the function main could be declared like
int main( void ){
So the program can look like
#include <stdio.h>
char test( void );
int main( void )
{
char c = test();
printf( "num = %c\n", c );
return 0;
}
char test( void )
{
char c = 'z';
return c;
}
You are calling test before it's declared. Either declare it before the main function, or provide its prototype:
/* Prototype of test */
char test();
int main(int argc, char * argv[]) {
char c = test();
printf("num = %c \n", c);
}
char test() {
char c = 'z';
return c;
}
So, I have been working on this simple block of code. I would like it to print, when I type in "./a.out -n"
However, that is not working. I have been on stackoverflow trying to work on this, but no such luck. Any help would be appreciated.
#include <stdio.h>
#include <stdlib.h>
void parse_cmdline(int argc, char *argv);
int main (int argc, char *argv[]) {
parse_cmdline(argc, argv);
}
void parse_cmdline(int argc, char *argv)
{
int x,i,m,n = 0;
if (*(++argv) == 'n'){
x = 1;
printf("Output array: "); /* not being displayed*/
}
}
Just write
if (**++argv == 'n'){
And the function should be declared like
void parse_cmdline(int argc, char **argv);
Otherwise you should specify what parameter you are going tp pass to the function. For example
parse_cmdline(argc, argv[1]);
You can check what parameters are passed to the program the following way
int main (int argc, char *argv[]) {
for ( int i = 0; i < argc; i++ ) puts( argv[i] );
}
Try:
#include <stdio.h>
#include <stdlib.h>
void parse_cmdline(int argc, char *argv[]);
int main (int argc, char *argv[]) {
parse_cmdline(argc, argv);
}
void parse_cmdline(int argc, char *argv[])
{
int x,i,m,n = 0;
if (*(argv[1]) == '-' && *(++argv[1]) == 'n'){
x = 1;
printf("Output array: "); /* not being displayed*/
}
}
And run it with ./a.out -n.
So, I have examined 0th and 1th character of the argv value on the position one ("./a.out" is located on position 0, and "-n" on position 1).
Is that what you wanted?
Also, you cannot ignore warnings:
1.c: In function ‘main’:
1.c:5:23: warning: passing argument 2 of ‘parse_cmdline’ from incompatible pointer type [-Wincompatible-pointer-types]
parse_cmdline(argc, argv);
^
1.c:3:6: note: expected ‘char *’ but argument is of type ‘char **’
void parse_cmdline(int argc, char *argv);
If you write
parse_cmdline(argc, argv);
then parse_cmdline should be
void parse_cmdline(int argc, char *argv[]);
#include <stdio.h>
#define MAX 9
void main (int argc, char *argv[]) {
printBoard();
}
void printBoard(void) {
int row,col;
row=col=0;
for(row;row<MAX;row++) //row navigation
for(col;col<MAX;col++){//column navigation
printf("r:%d,c:%d",row,col);
}/*End Column Nav*/
printf("\n");
}
I'm not sure what I am doing wrong here - the error I get :
"warning: conflicting types for ‘printBoard’ [enabled by default]
note: previous implicit declaration of ‘printBoard’ was here"
Try adding a function prototype for printBoard above main() e.g.,
void printBoard(void);
void main(...)
You have declared function after calling it.
#include <stdio.h>
#define MAX 9
void printBoard(void) {
int row,col;
row=col=0;
for(row;row<MAX;row++) //row navigation
for(col;col<MAX;col++){//column navigation
printf("r:%d,c:%d",row,col);
}/*End Column Nav*/
printf("\n");
}
void main (int argc, char *argv[]) {
printBoard();
}
This should work pretty fine.
Edit: You should declar all function before calling any of them.
Like void printBoard(void);
You are calling the method before it is declared.
Solve the problem by:
1) Moving the definition of void printBoard(void) above main or
2) adding a declaration above main. Just this line: void printBoard(void);