I found a code and I want to use it. When I run it from a terminal by ./code 20181010 0810, it works perfectly.
I was trying to rewrite this code into function. The main code was declared by
int main (int argc, char *inp[]) { //some calculations }
So, I changed it into:
int calc(int argc, char *inp[]) { //some calculations }
and the write main code with additional calculations:
int calc(int argc, char *inp[]);
int main(int argc, char *inp[]) {
char* c_date;
char* c_hour;
time_t timer;
char buffer1[26], buffer2[26];
struct tm* tm_info;
time(&timer);
tm_info = localtime(&timer);
strftime(buffer1, 26, "%Y%m%d", tm_info);
c_date = buffer1;
strftime(buffer2, 26, "%H%M", tm_info);
puts(buffer2);
c_hour = buffer2;
calc(&c_date, &c_hour);
return 0;
}
And for example, for the time now 20180212 1045 it gives me 201802112355, when it should give me 201802121050.
What can be wrong?
At present you’ve just copied the main prototype. What does the function body of calc do? If you had an exact copy of the main function then...
int calc(int argc, char *inp[]);
argc is the number of arguments being passed into your program from the command line and inp is the array of arguments.
You’re passing in &c_date as argc
But that really depends what’s within the calc function......
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);
});
};
why I am not succeed
int main(char* name,int arg0,int arg1)
{
name = "/u/e2014/Desktop/os/Prog.c";
arg0 = 0;
arg1 = 1;
char my_args[3];
my_args[0] = arg0;
my_args[1] = arg1;
my_args[2] = NULL;
execl(name,m_args);
return(0);
}
I want that my program will execute the program in the path "name".
Right now its do nothing.
I am not understand where is my mistake?
I program in C on linux, and compile it with gcc
Thanks a lot!!
gcc has 3 different signature for main function
int main(void);
int main(int argc, char* argv[]);
int main(int argc, char *argv[], char *envp[]);
Your main function doesn't match either of these. therefore compiler error.
For your case you can use the 2nd signature with a small modification.
#include <stdlib.h>
int main(int argc, char **argv)
{
char *path;
int int1, int2;
path = argv[1];
int1 = atoi(argv[2]);
int2 = atoi(argv[3]);
}
First you are passing wrong parameter in int main(). main() has at least 3 args only.
int main(int argc, char*argv[], char *envp[]);
To execute your program you should use execvp() because you passing arrey of char* not command-line arguments via a variable-argument.
difference between execl and execv?
**L vs V: whether you want to pass the parameters to the exec'ed program as
L: individual parameters in the call (variable argument list): execl(), execle(), execlp(), and execlpe()
V: as an array of char* execv(), execve(), execvp(), and execvpe()**
#include <stdio.h>
#include <unistd.h>
int main(int argc,char*argv[])
{
char *name = "/root/a.out";
char *arg0 = "0";
char *arg1 = "1";
char *my_args[4];
my_args[0] = name;
my_args[1] = arg0;
my_args[2] = arg1;
my_args[3] = NULL;
execvp(my_args[0],my_args);
return(0);
}
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.
I have this homework to do in C. I'm beginner so it is probably very easy, but anyway I have a problem with it.
int main(int argc, char* argv){
int fd=open(argv[1], O_RDONLY);
int fileLength=(int)lseek(fd,0,SEEK_END);
lseek(fd,0,SEEK_SET);
char buf[fileLength];
read(fd,buf,fileLength);
int i=0;
for(i=0; i<fileLength; i++){
printf("%c",buf[i]);
}
printf("\n");
}
I get this error:
warning: passing argument 1 of ‘open’ makes pointer from integer without a cast
If I write "file" instead of argv[1], everything is ok.
int main(int argc, char* argv){
has to be:
int main(int argc, char *argv[])
See the error?
char* argv should be char* argv[]
What you did is declaring argv as char* and then argv[1] becomes a char (which is an integer) instead of char *
The correct signature is
int main(int argc, char **argv)
Your problem is in main() declaration, which should be:
int main(int argc, char *argv[])
You defined argv as a char *, which makes it a single pointer, whereas it's an array of char * pointer, with each char * element corresponding a command line argument to your program.
The error you're getting is caused by the fact that when you pass argv[1] to open(), argv[1] is a single char, while open() expects a char *.
Another improvement to your program would be checking that argc > 1 before attempting to use argv[1]. This would catch cases when you didn't pass any arguments to your program.
argv should be a char ** not a char * also you should run the program like
./program filename
Your main function's signature is wrong.
It should look like this:
int main(int argc, const char *argv[]) // notice how 'argv' is now a 'const char *[]',
Try this mate:
main () {
FILE *fin = fopen ("test.in", "r");
FILE *fout = fopen ("test.out", "w");
int a, b;
fscanf (fin, "%d %d", &a, &b); /* two input integers */
fprintf (fout, "%d\n", a+b);
exit (0);
}
instead of "test.in" put your argument, did you try to cast first before?