I have below code where I am passing address of array of charectors to function "GetStr". GetStr function prototype is fixed.
Here in below code I am passing command line argument where string to function "GetStr" and update the value in the address of variable "str".
PRoblem:
At Print 1, I am getting the value what I passed from command line arguments. A Print 2 in main function, I am unable to print or get the value back. Could you please let me know how to print the value at "Print 2" statement
int GetStr(void *RetVal, int argc, char **argv)
{
if(argc != 0){
if(argv != NULL && argv[1] != '\0'){
RetVal = argv[1];
}
else{
RetVal = '\0';
}
cout<< " RetVal: " << (char *)RetVal <<endl; ->>> PRINT 1
}
else{
return -1;
}
return 0;
}
Driver:
int main(int argc, char **argv)
{
char str[8];
GetStr(str,argc,argv);
cout<<"HH: "<<((char *)(str))<<endl; ->>> PRINT 2
}
You have to use strcpy() to copy a string. You're just assigning the address of argv[1] to the local variable RetVal, which has no effect on the array in the caller.
You should also check argc to determine if argv[1] has been supplied.
int GetStr(void *RetVal, int argc, char **argv)
{
if(argc != 0){
if(argv != NULL && argc >= 2){
strcpy((char*)RetVal, argv[1]); // copy first argument
}
else{
*(char*)RetVal = '\0'; // Set to empty string
}
cout<< " RetVal: " << (char *)RetVal <<endl; ->>> PRINT 1
}
else{
return -1;
}
return 0;
}
Note that it's necessary to cast RetVal before indirecting through it in the assignment, because you can't dereference a void pointer.
The parameter RetVal is a local variable of the function GetStr. Changes of it do not influence on the original argument passed to the function. Moreover as the original argument is an array then arrays do not have the assignment operator. You have to copy characters pointed to by argv[1] to the passed array.
So in any case this statement
RetVal = argv[1];
and this
RetVal = '\0';
have no effect relative to the passed array. And it is unclear what you are trying to do in the second statement above. Either you want to set the pointer to NULL. Or you want to set the first pointed byte to the terminating zero character that is invalid because the pointer is not dereferenced and moreover has the type void *.
Also it seems that instead of this expression in the if statement
argv[1] != '\0'
you mean either
argv[1][0] != '\0'
or
argv[1] != nullptr
In any case these two if statements
if(argc != 0){
if(argv != NULL && argv[1] != '\0'){
can be substituted for one if statement as
if ( not ( argc < 2 ) )
The function can look at least the following way
int GetStr( void *RetVal, int argc, char **argv )
{
int error = argc < 2 ? -1 : 0;
if ( not error )
{
strcpy( RetVal, argv[1] );
}
return error;
}
The function should not output anything except for the debug purpose. It is the caller of the function will decide whether to output a message if any.
Pay attention to that the function is unsafe because the passed array can be less than it is required to copy the string pointed to by argv[1].
Related
So I have the following function, which splits the char* input by spaces and adds each char* to a char** which is finally returned.
char **split_input(char *input) {
char **command = (char **)malloc(8 * sizeof(char *));
const char *separator = " ";
char *parsed;
int index = 0;
parsed = strtok(input, separator);
while (parsed != NULL) {
command[index] = parsed;
index++;
parsed = strtok(NULL, separator);
}
command[index] = NULL;
return command;
}
I was wondering if there is any way of getting the amount of char* that the returned char** contains.
I was wondering if there is any way of getting the amount of char* that the returned char** contains.
Given the code you have shown, there is only 1 way - the caller will have to iterate the array counting elements until it reaches the NULL at the end.
Otherwise, tweak the function to return the array count alongside the array pointer, either as an optional output parameter, or use a std::pair<char**, int> or struct { char**; int; } as the return value.
The problem enlies with printf(stringOut). It prints an empty array. The function halfstring appears to work correctly but the string it builds never makes it to main.
int main(int argc, char *argv[])
{
char stringIn[30] = "There is no cow level.\0";
char stringOut[sizeof(stringIn)];
halfstring(stringIn, stringOut);
printf(stringOut);
return 0;
}
halfstring is supposed to take every odd character in a char array and put it into a new char array without using ANY system-defined string functions (i.e. those found in the string.h library including strlen, strcat, strcpy, etc).
void halfstring(char stringIn [], char stringOut [])
{
int i = 0;
int modi;
while(stringIn[i] != '\0')
{
if(i % 2 != 0)
{
stringOut[i] = stringIn[i];
}
i++;
}
}
Inside the function halfstring you skipped the first and second characters of stringOut which probably are containing null characters when being declared this is the reason why you got nothing.
You can solve that by adding a new separate indice k for stringOut:
void halfstring(char stringIn [], char stringOut [])
{
int i = 0,k=0; // create a separate indice for stringOut
int modi;
while(stringIn[i] != '\0')
{
if(i % 2 != 0)
{
stringOut[k] = stringIn[i];
k++; // increment the indice
}
i++;
}
stringOut[k]='\0';
}
1) You don't need to NUL terminate a string literal:
char stringIn[30] = "There is no cow level.\0";
^^
2) Your second array (stringOut) results in something like:
{'T', garbage, 'e', garbage, 'e', garbage, 'a', garbage, 'e' ... };
You need to count the number of chars stored in the 2nd array:
void halfstring(char stringIn [], char stringOut [])
{
int i = 0;
int n = 0;
while(stringIn[i] != '\0')
{
if(i % 2 != 0)
{
stringOut[n++] = stringIn[i];
}
i++;
}
stringOut[n] = '\0';
}
There are several drawbacks in the program.
For starters there is no need to include the terminating zero in the string literal
char stringIn[30] = "There is no cow level.\0";
^^^^
because string literals already have the terminating zero.
Secondly usually standard string functions return pointer to the first character of the target string. This allows to chain at least two functions in one statement.
The first parameter is usually declares the target string while the second parameter declares the source string.
As the source string is not changed in the function it should be declared with the qualifier const.
And at last within the function there is used incorrect index for the target string and the string is not appended with the terminating zero.
Taking this into account the function can be written as it is shown in the demonstrative program below
#include <stdio.h>
char * halfstring( char s1[], const char s2[] )
{
char *p = s1;
while ( *s2 && *++s2 ) *p++ = *s2++;
*p = *s2;
return s1;
}
int main(void)
{
char s1[30] = "There is no cow level.";
char s2[sizeof( s1 )];
puts( halfstring( s2, s1 ) );
return 0;
}
Its output is
hr sn o ee.
Help please how to finish function.
I got exersize for develop function for searching substring in string and return first position of enter.
That is code what i made:
int strstr(const char *str, const char *pattern) {
const char *st = str; // assign adress of string to pointer
const char *pa = pattern; //assign adress of pattern what we must find in string to pointer
while (*st){ // starting sort out string
++st;
if( *st == *pa){ //when first symbol of pattern equal to symbol of string starting the loop
int i = 0; //counter of iteration for possibility to return first enter of substring
for(i;*st == *pa;i++){ //that loop sort out every next symbol of string and pattern for equality
++st;
++pa;
} //loop finish when pattern or string was ended, or any next symbol was not equal
if(*pa == 0){ //if patter was ended return position of first enter
return st-i; //there not compiling((
}
pa-i; //reset pattern
st-i; //reset string
}
}
return -1; //return -1, if substring was not find
}
For hard luck that code not compiling... Error is invalid conversion from ‘const char*’ to ‘int’
What type must be variable i for that? And check my logic please)
return st-i; //there not compiling((
You are returning a pointer to a constant char, where your function requires to return an integer. My best guess is you need to change it into:
return *(st-i)
Use the * to dereference the pointer into the const char object, which is interchangeable with int
The problem is that your function is currentlu defined to return an int.
If you desire to return an int, such as the relative position from the beginning of your string, then you have to return a difference between pointers
return (st-i)-str; // st-i = begin of the pattern found, - str for the relative position
If you desire to return a pointer, then your function signature shall be changed and you should return nullptr instead of -1 when you didn't fin the patter.
Several other minor issues:
incrementing st before starting comparison risk to miss the pattern if the string starts with it.
pa-i and st-i are without effect: it's just expressions, no change is stored. Maybe you wanted to write pa-=i ?
Try the following. At least it looks simpler.:)
#include <iostream>
int strstr( const char *str, const char *pattern )
{
bool found = false;
const char *p = str;
for ( ; *p && !found; ++p )
{
size_t i = 0;
while ( p[i] == pattern[i] && pattern[i] != '\0' ) ++i;
found = pattern[i] == '\0';
}
return found ? --p - str : -1;
}
int main()
{
std::cout << ::strstr( "Hello evsign", "evsign" ) << std::endl;
return 0;
}
The output is
6
As for your code then even the first statement in the loop is wrong
while (*st){ // starting sort out string
++st;
Why is st increased?
Also this loop
for(i;*st == *pa;i++){
shall be written as
for( ;*st == *pa && *pa; i++){
This is a homework assignment first off.
We have to create a "common application-programming model in UNIX/Linux known as the filter".
I'm stuck on reading the input passed through as arguments (it's all I ever seem to have trouble on).
For example, the cmd is open and the following line is entered:
program -isomebinaryfile.bin
I need to determine what the first letter is after the hyphen (-) and so on and so forth.
Is scanf what I would be using? My main is set up to be able to accept arguments:
int main (int argc, char *argv[])
{
FILE *inf = NULL;
char *arg = argv[0];
}
Can someone give me a little help?
Unless your assignment is only to handle processing of arguments, you may want to look up getopt - it's a standard library parser for arguments.
As for the meat of your question, there are a lot of options, and you could use sscanf as part of it, but you don't have to.
To parse the one argument you mentioned, you need to do the following: check if the argument begins with -i, grab the data out of the argument.
The easiest way to check if the argument begins with -i is:
if (argv[1][0] == '-' && argv[1][1] == 'i')
Alternatively, if you have a lot of argument options, all beginning with '-', you may want something like:
char * i = NULL;
char * o = NULL;
char * s = NULL;
for (int i = 1; i < argc; ++i) {
if (argv[i][0] == '-') {
switch(argv[i][1]) {
case 'i':
i = argv[i][2];
break;
case 's':
s = argv[i][2];
break;
case 'o':
o = argv[i][2];
break;
default:
cerr << "Unknown option: " << argv[i][1];
}
} else {
cerr << "Error: all options must begin with '-'";
}
Note, I'm using argv[1], not 0. argv[0] is always the name of the executable.
The fastest way to extract the rest of the argument is simple pointer arithmetic:
char * filename = argv[1] + 2; // (Or you could equivalently say = &argv[1][2]
This is most efficient - it reuses the strings that are already in argv. If you're planning on changing the strings around, you'd do better with strcpy:
char * filename = (char *)malloc(strlen(argv[1]) - 2);
strcpy(filename, argv1 + 2);
// and eventually you'd have to free(filename)...
Play around and experiment with all the string functions. You'll find them essential to all of your later programs.
You need to use getopt. The manual page has an example.
argv is an array of strings. You can loop over them like
for (int i=1; i<argc; i++) { // skip argv[0] as that's this program's name
const char* arg = argv[i];
}
Once you have the string for a particular argument, you can use the string manipulation functions from <string.h>
if (arg[0] == '-' && strlen(arg) > 0) {
arg++; // advance past the leading '-'
if (strcmp(arg, "command_one") == 0) {
// handle command_one
}
else if (strcmp(arg, "command_one") == 0) {
....
else {
printf("Error: unexpected command %s\n", arg);
}
Get arguments from argv ("argument vector"). In your example, argc and argv will be as follows:
argc == 2
argv[0] == "cmd"
argv[1] == "-isomebinaryfile.bin"
Finding the first letter after the hyphen in argv[1] is a simple loop.
How can I write a program to check the arguments in the terminal are correct?
For example, if I have a program hello.cpp and I want to call it as:
./hello yes 10
I want the program to make sure that the first argument is yes or no and the second argument is a number between 1-10. So how can I read these arguments into my program to do the checking?
Thanks!
Command line arguments are passed as a count and individual strings in the argc and argv arguments to main().
int main(int argc, char *argv[])
{
...
}
Simply check the value in argc and the strings in argv for the appropriate values.
You meant to execute like this, ./hello yes 10
there is an option argc and argv in c
where argc is the number of arguments passed and argv with the index shows the argument passed itself.
Take a look at the below code for iterating through all arguments.
int main(int argc, char *argv[]){
int i = 0;
for (i = 0; i < argc; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
return 0;
}
As mentioned by other users, The main function is the entry point of your program, and the way it gets data from the command line is through its parameters.
The first int argument is the count of all the arguments passed, including the program name, the second char ** argument is a pointer to each parameter passed, including the program name:
int main
(
int argc, // <-- how many parameters has been provided?
char **argv, // <-- what values has each parameter?
)
{
...
return 0;
}
So, knowing that, your call ./hello yes 10 must be like that:
argc = 3
argv[0] = "./hello"
argv[1] = "yes"
argv[2] = "10"
The names argc and argv are just a convention, you can name them at your pleasure, but it's a good practice to keep the names that everyone are used for.
And the argument doesn't are forced to be int, char ** they must follow a quite rigid convention, borrowed from this answer:
It shall have a return type of type int, but otherwise its type is implementation-defined. All implementations shall allow both the following definitions of main: int main() and int main(int argc, char* argv[])
Knowing that, let's focus on your question:
First of all, you must ensure that 2 arguments are passed, so you must check the argc value and ensure that equals exactly 3.
the first argument is yes or no
Next, you must store your argv[1] (because 0 contains the program name) into a string and compare it with the values "yes" and "no":
std::string YesOrNo(argv[1]);
if (YesOrNo == "yes" || YesOrNo == "no")
And finally, you must store your argv[2] into an integer and check if it is equal or less to 10:
std::stringstream Stream;
int Value = 0;
Stream << argv[2];
Stream >> Value;
if (Value <= 10)
So, the result is:
int main(int argc, char **argv)
{
if (argc == 3)
{
std::string YesOrNo(argv[1]);
if (YesOrNo == "yes" || YesOrNo == "no")
{
std::stringstream Stream;
int Value = 0;
Stream << argv[2];
Stream >> Value;
if (Value <= 10)
{
// Your stuff..
}
}
}
return 0;
}
I let you deal with all the uppercase and lowercase stuff and the false positives with the numeric argument, at least I'm not going to do all your homework ;)