Error in copying argv to char array - c++

I am trying to copy argv to char array, been through some solutions online but ending up in getting Segmentation Fault. Following is the code i used:
void main (int argc,const char *argv[])
{
char *arr;
arr = (char *) malloc(strlen(argv[1])+1);
strcpy(arr,argv[1]);
}
Please help to identify what I am doing wrong.

It seems that argv[1] is equal to NULL or even does not exist (The C Standard allows that argc may be equal to 0).
Add the following check
char *arr;
if ( argc > 1 )
{
arr = (char *) malloc(strlen(argv[1])+1);
strcpy(arr,argv[1]);
}
else
{
// print some error message
}

Please help to identify what I am doing wrong.
All right then sir. You are asking for argv[1], but you are not sure whether it exists. accessing an array outside its bounds has undefined behavior. You should always check if number of parameters is what you expect to avoid undefined behavior:
if ( argc < 2 )
{
// error, cannot copy argv[1] because it doesn't exist. Explain this to user
}
// now OK..., also we postponed allocation of arr pointer
char *arr = malloc( strlen( argv[1]) + 1);
//^^^^
// no need to cast return value of malloc in C
strcpy( arr, argv[1]);

When using command line input, we should deal with number of arguments.
You can try something like this..
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void main (int argc, const char *argv[])
{
if(argc==2)//change condition based on your requirements
{
char *arr;
arr = (char *) malloc(strlen(argv[1])+1);
strcpy(arr,argv[1]);
printf("string is %s\n",arr);
}
else
{
printf("check your command line input (only 2 parameters)\n");
}
}
OUTPUT:
$ ./a.out
check your command line input (only 2 parameters)
$ ./a.out hello
string is hello
$ ./a.out hi hello
check your command line input (only 2 parameters)
$

Related

Number of elements of command line arguments

I have a problem with command-line arguments.
I need to write a program that will count the size of elements of each command-line argument passed in argv array.
Simple code looks like this.
#include <stdio.h>
int main(int argc, char *argv[])
{
int i = 0;
for (i = 0; i < argc; i++)
{
printf("%lu\n", sizeof(argv[i]));
}
return 0;
}
I understand that it is wrong and that "argv" is an array of pointers to a string. I also tried to add asterisk but it brought back "1" (byte) as a result because I said "go to that address" and it showed me the size of the first element of each command-line argument.
So, how can I solve this problem without many and many loops, just with "sizeof" function?
UPD: Sorry for that "%s" mistake. In the actual code I didn't write it.
And I DO understand that sizeof() won't bring me the size of array. I was pointing to the combination "sizeof() / sizeof (char)"
Also, thank you very much for "strlen" reminder. I am studying now. I don't know C language yet. Sorry, for my stupid mistakes.
You are printing the size of a character pointer. Instead you want the length of the string. You can use the standard function strlen :
( note: argv[0] is the program name itself, so 1st number indicates the length of program name.)
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
int i = 0;
for (i = 0; i < argc; i++)
{
printf("%zu\n", strlen(argv[i]));
}
return 0;
}
Instead of sizeof use strlen() that returns the size of a string while excluding the string termination character from the counting. More information here: Strlen
As it is seen from your program more preciseky from the declaration of the main arguments have type char *. That is they are pointers to first characters of strings that are passed to the program like arguments.
So you need to use standard C function strlen declared in header <string.h> to determine the size of the string passed like an argumnet.
Take into account that the last pointer in the array argv has value NULL.
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
for ( char **p = argv; *p; ++p )
{
printf( "%zu\n", strlen( *p ) );
}
return 0;
}

how can I test argc and then assign default values to argv[1]?

I need to give default behavior to a command line app if no arguments are entered.
If no arguments are entered, I need the program to set argv[1][0] = '1' and argv[1][1] = '\0' for the null terminator.
I keep getting a core dump when I try to compile my code in g++, and here is what is causing the issue:
int main(int argc, char * argv[]){
//for testing we put some dummy arguments into argv and manually set argc
//argc = 1;//to inlcude the program name
//we put a defualt value into argv if none was entered at runtime
if(argc == 1){
argv[1][0] = '1';
argv[1][1] = '\0';//add a null terminator to our argv argument, so it can be used with the atoi function
}
Also, I am not on C++ 11.
RE-FACTORED CODE: (Which basically just codes around the issue so that we don't have to manipulate argv[] in the main function)
int argvOneAsInt;
if(argc != 1){
argvOneAsInt = atoi(argv[1]);//use atoi to convert the c-string at argv[1] to an integer
}
else{
argvOneAsInt = 1;
If argc equals 1, then the second value in the array argv is NULL. You are dereferencing that NULL pointer right here:
argv[1][0] = '1';
Instead of trying to manipulate argv, rather change the logic in the code. Use an array you control in memory, copy argv to it and then manipulate the array.
This all looks rather dodgy. I would probably do something like this:
int main(int argc, char* argv[])
{
std::string arg1 = "1"; // set default
if(argc > 1) // override default if present
arg1 = argv[1];
// Now use arg1 and forget about argv[]
}
just to support your question, what ever you wanted was not faulty but you forgot to allocate memory where you wanted to assign your values.
Check this:
#include <string.h>
#include <malloc.h>
using namespace std;
int main(int argc, char * argv[]){
//for testing we put some dummy arguments into argv and manually set argc
//argc = 1;//to inlcude the program name
//we put a defualt value into argv if none was entered at runtime
if(argc == 1){
argv[1] = (char*)malloc(strlen("1\0"));
argv[1][0] = '1';
argv[1][1] = '\0';
//argv[1][2] = '\0';
//argv[1] = '\0';//add a null terminator to our argv argument, so it can be used with the atoi function
}
}
now it should work the way you want.

argv[1] giving segfaults

I have the following code:
int main(int argc, char *argv[])
{
if(strcmp(argv[1],"-e")==0)
{
//perform code
}
//code if argv[1] is not "-e"
return 0;
}
When I take out the whole if statement:
if(strcmp(argv[1], "-e")==0)
my code if strcmp(argv[1], "-e") == 0) is not "-e" works fine. But when I leave it in, my code only works for when the if statement above produces true. Any ideas on why this may happen? For example:
If I compile with argv[1] not commented out:
//example program will be an executable
exampleProgram -e < a.txt works but exampleProgram < a.txt doesn't work. Any ideas why?
Simple, if you don't send any argument to the program then args[1] doesn't exist and you are trying to access to an unassigned memory position.
You may do something like this:
int main(int argc, char *argv[])
{
if(argc > 1 && strcmp(argv[1],"-e")==0)
{
//perform code
}
//code if argv[1] is not "-e"
return 0;
}
argv is an array. When you try to index into array beyond last element you get segfault. To not go past the last element check the value of argc, and argc - 1 will be the index of the last element you can access. More on segfaults here: http://en.wikipedia.org/wiki/Segmentation_fault
the reason
exampleProgram -e < a.txt works and
exampleProgram < a.txt doesn't
is because when there is no argument being passed into the program, where is no argv[1], it is out of bounds of the args array. what you need to do before testing argv[1] is test to see if there are that many arguments to begin with.
For example:
if (argc > 1) {
if(strcmp(argv[1],"-e")==0) {
}
}
argc is used to hold how many arguments exist in the program so you can test this before going out of bounds.

Segmentation Fault With argv

I have a program that reads in a single argument from the command line and performs certain operations on it. I'm using argv and argc. When I fail to pass an argument to the program, it segfaults. I've tried checking if argc isn't a certain value and then printing the value out, but it still segfaults. Here's the code in question. Note that it works as expected when passed a single argument. Here's the code in question:
int main(int argc, char *argv[])
{
int numTimes = atoi(argv[1]); //converts content of argv[1] into integer
if(argc != 2)
{
printf("Enter a valid integer.");
}
You need to check argc before you try to access that argument. Just move the argc test to sometime before before you call atoi(argv[1]).
Just check the number of arguments before trying to accessing a specific element. Something like this:
int main(int argc, char *argv[])
{
if(argc < 2)
{
printf("Enter a valid integer.");
return 0;
}
int numTimes = atoi(argv[1]); // now we're sure to have at least 1 argument passed
// ...
}
You have to do the check before attempting to access the arguments.

c, c++ most basic double quotes

char* a="HELLO WORLD";
IF ADDRESS of 'H' is 0x01 then the printf with %s prints to D but if the same code is written with manual printing routine
while(*a!=NULL) {printf("%c",n[a]);n++;}
this prints a few more characters..
but
printf("%s",a);
prints it perfectly.
while(*a++) printf("%c", *(a-1)); or
for(;*a++;)printf("%c", *(a-1));
although work but i dont want solutions but the process mechanisms..
so the question coming to my mind is
whether printf gets the length of the string from some register(or any memory unit)
or it performs character check.. then prints...
The way you're indexing into the character string is odd. It works for the string, but won't stop because you never change the value of *a. What your program does is try to get the a offset of n, so for the first 11 positions they are the same, but the loop doesn't terminate because *a will always be 'H'. What you'd want the terminating condition to be is n < strlen(a).
However, the more succinct way to write that program would be:
int main(int argc, char **argv) {
char *a = "HELLO WORLD";
while(*a) printf("%c", *a++);
return 0;
}
This works because a is an array of characters and as we're printing out each character (de-referencing the value stored at the position) we also increment to the next position. The string should terminate with a NULL reference, which will cause the loop to terminate sine *a == 0 at the NULL terminator.
did you mean or you have error:
int main() {
int n = 0;
char* a="HELLO WORLD";
while(a[n] != NULL) {printf("%c",a[n]);n++;}
}
explanation about what is wrong:
while(*a!=NULL) printf("%c",n[a]);n++;
a is not modified anywhere, so *a will not change it's value.
Although n[a] is perfectly valid construct in C I strongly recommend not to use it, because it is semantically incorrect. You access array by index, not index by array.
You increment index (n++) but check the pointer to array. You could possibly increment a inself like this: while(*a!=NULL) {printf("%c",*a);a++;}
The corect way to do this is:
#include <iostream>
using namespace std;
int main() {
char *a="HELLO WORLD";
int n = 0;
while(a[n]!=NULL){
cout<<a[n];
n++;
}
cout<<'\n';
return 0;
}
As far as I remember, by default when you created char* a it will be something as {HELLO WORLD\0} in memory ('\0' is how %s know the end of the your string is)..
Not sure if '\0' == null will yield true.. but I doubt it