invalid initializer error for argv[0] and argv[1]? - c

Whenever I compile my c program, I get this error for both of my argv[]'s.
error: invalid initializer
char baseDir[] = argv[0];
error: invalid initializer
char pattern[] = argv[1];
This is a snippet of the main method in my program.
void walkDir(char *baseddir, char *pattern);
int main(int argc, char *argv[]){
char baseDir[] = argv[0];
char pattern[] = argv[1];
walkDir(baseDir, pattern);
if(count==0){
printf("No match found \n");
}
printf("\n Done \n");
return 0;
}

argv[0] and argv[1] are char*. They point at strings of unknown length. argv[0] usually holds a pointer to the name of the program itself while argv[1] holds a pointer to the first argument supplied to the program.
To initialize a char[] you need something like this:
char baseDir[] = "a string literal";
In your case, it's not a string literal so you can't initialize a char[] with it, so you probably should just copy the pointers:
const char *baseDir = argv[1]; // a pointer to the first argument
const char *pattern = argv[2]; // a pointer to the second argument
I added const since you shouldn't change the strings they are pointing at. I suppose you are not planning to change the strings in your walkDir function either, so then change it accordingly:
void walkDir(const char *baseddir, const char *pattern)

Related

In C, how to set an unsigned char array from argv

In the code below, I would like to have the value of myvar be provided by a program argument.
#include <stdio.h>
int main(int argc, const char **argv)
{
const unsigned char myvar[] = "myvalue";
return 0;
}
How would I get myvar to contain the value of the string from argv[1]?
If you are only reading, then you can simply copy the address of argv[1] like this:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char **argv) {
const unsigned char *myvar = NULL;
// Be sure to check argc first
if (argc < 2) {
fprintf(stderr, "Not enough arguments.\n");
return EXIT_FAILURE;
}
myvar = (const unsigned char *)argv[1];
printf("myvar = %s\n", myvar);
}
If you want to change myvar then you should copy the string with strncpy or alike.
An array cannot be initialized by a pointer or by another array. You can only initialize it with an initializer list or (in the char of a char array) a string constant.
What you can do it copy the contents of another string with strcpy. And since you'll be using this array as a parameter to an encryption function, it will probably need to be a fixed size.
char myvar[8] = { 0 }; // initialize all values to 0
strncpy(myvar, argv[1], 8); // copy the first 8 bytes

Copying a char array to another const char array during declaration

What I am trying to do is take a string pointed to by argv[1] and copy it into another array, but I want this new array to be const.
Is there a way to declare the array as const and initialize it with the contents of argv[1] on the same line?
The problem I'm having is that I can't declare it as const and then on the next line copy the string over using strcpy or some such function. That's invalid.
What's the best course of action?
You could do something like this:
#include <stdio.h>
int main(int argc, char *argv[])
{
const char *argument = argv[1];
printf("%s\n", argument);
return 0;
}
leveraging the fact that argument[0] is substantially the same of *argument.
But beware!
int main(int argc, char *argv[])
{
const char *argument = argv[1];
printf("%s\n", argument);
argument[2] = 'z'; //ERROR
printf("%s\n", argument);
return 0;
}
this above causes an error as expected. But...
int main(int argc, char *argv[])
{
const char *argument = argv[1];
printf("%s\n", argument);
argv[1][2] = 'z'; //same memory location but no errors
printf("%s\n", argv[1]);
printf("%s\n", argument);
return 0;
}
causes no error .... in fact in the last printf you can see that your string has been edited.
Considering you don't want to modify it (it being a const and all), you don't even need to copy it somewhere:
(Basic code lacking sanity checks such as correct argument count and argument lenght)
const char *myPointer = NULL;
myPointer = argv[1];
Now myPointer is pointing to argv[1], your first argument that the program was launched with.
So if you launch your program like myfolder/myexe.exe myArg your myPointer will point to a char array with these contents {'m','y','A','r','g','\0'}

Changing a string pointer in C [duplicate]

This question already has answers here:
C function change string using pointer
(3 answers)
Closed 8 years ago.
Apparently I'm a member of a large club that just doesn't understand C-style pointers correctly. Here's my program:
void changethestring (const char * thestring)
{
thestring = "string two";
}
int _tmain(int argc, _TCHAR* argv[])
{
const char * teststring = "string one";
changethestring(teststring);
printf("The string is: %s.\n", teststring);
return 0;
}
My intent is that changethestring() should cause the pointer to point to "string two". My logic is that I'm giving the function a pointer. The function should be able to change the pointer to point to a different area in memory. And that change should persist outside the function.
Yet that's not what happens. In the printf() statement, the string is still "string one".
Can anyone explain why this is, what's happening under the covers, and how I can write a function changethestring() to change the string to which the pointer points?
You should give pointer to a pointer instead of just pointer. The reason for this is that in C, all arguments are sent by value. So in order to change the value of a variable which is a pointer, you need to send a pointer to this variable, therefore, pointer to a pointer.
UPDATE: You can define string literal outside of the changethestring function, but it's not needed, because string literals are stored in a global string table for the whole lifetime of the program. So both this:
const char* STRING_TWO_LITERAL = "string two";
void changethestring (const char ** thestring)
{
*thestring = STRING_TWO_LITERAL;
}
int _tmain(int argc, _TCHAR* argv[])
{
const char * teststring = "string one";
changethestring(&teststring);
printf("The string is: %s.\n", teststring);
return 0;
}
and this:
void changethestring (const char ** thestring)
{
*thestring = "string two";
}
int _tmain(int argc, _TCHAR* argv[])
{
const char * teststring = "string one";
changethestring(&teststring);
printf("The string is: %s.\n", teststring);
return 0;
}
should work.
By passing the pointer by value, it will get back to its initial value when you exit your function.
You should pass it by reference as Ashalynd suggest or you can also return a new value for this pointer:
const char * changethestring (const char * thestring)
{
thestring = "string two";
return thestring;
}
int main(void)
{
teststring = changethestring(teststring);
}

In C, strings giving me warnings about initialization discarding qualifiers

I am getting the following warning for two lines of my code.
initialization discards qualifiers from pointer target type
The two lines are the sources of the warning.
function (const char *input) {
char *str1 = input;
char *str2 = "Hello World\0";
}
I think the first line gives an error because I try to assign a const char* to a char*. How would I fix that?
You need to declare it const:
const char *str1 = input;
void function (const char *input) {
char *str1 = input;
char *str2 = "Hello World\0";
}
in C an object of type char * cannot be initialized with an object of type const char *.
You have do this instead:
const char *str1 = input;
Also a string literal like "Hello World" is already null terminated, there is no need to add the null character yourself, do this instead:
char *str2 = "Hello World";

Passing char * vs char ** as parameters to a function in C

I've read several discussions of passing char * in C.
stackoverflow: passing-an-array-of-strings-as-parameter-to-a-function-in-c
stackoverflow: how-does-an-array-of-pointers-to-pointers-work
stackoverflow: whats-your-favorite-programmer-ignorance-pet-peeve
drexel.edu: Character arrays
Many of them include discussions of arrays, but I want to stay away from that.
I'm writing a sample program to teach myself about the passing of char * and char ** in C. This is an exercise in passing char *, without using (pointers to) arrays. Also no concerns for execution efficiency. :-)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void get_args_works(int, char **, char **);
void get_args_broken(int, char **, char *);
char *get_string(int, char **);
int main(int argc, char **argv)
{
char *string_works;
char *string_broken;
get_args_works(argc, argv, &string_works);
get_args_broken(argc, argv, string_broken);
printf("in main string_works (%p) = %s\n",string_works,string_works);
free(string_works);
printf("in main string_broken (%p) = %s\n",string_broken,string_broken);
free(string_broken);
}
void get_args_works(int argc, char **argv, char **string)
{
*string = get_string(argc, argv);
printf("in get_args_works %p string %s\n",*string,*string);
}
void get_args_broken(int argc, char **argv, char *string)
{
string = get_string(argc, argv);
printf("in get_args_broken %p string %s\n",string,string);
}
char * get_string(int argc, char **argv)
{
int i;
char *string;
string = malloc(40);
// placeholder in case -s switch not found below
strcpy(string,"-s switch not found below");
for(i = 0; i < argc; i++)
{
if(argv[i][0] == '-')
{
switch(argv[i][1])
{
case 's':
// release above malloc(40) for "-s switch not found below"
free(string);
// make room for storing variable
string = malloc(strlen(argv[++i]) + 1);
// the argv just after -s
strcpy (string,argv[i]);
break;
}
}
}
return string;
}
You can also view the same code on github
The above code is somewhat self documenting. main() declares two char * variables, and passes them as parameters to their respective get_args() functions.
Each get_args() function calls char * get_string(int, char **), using the exact same call (but different way to collect the return value).
get_string() works fine; it does a malloc() and returns the pointer back to the calling function. That code works, and each get_args() function receives the return value as I expect.
But then, when the get_args() functions return to main(), why does the dereferenced pointer value get back to main (from get_args_works(), but not the pointer's value (from get_args_broken())?
(i.e. I can see that if I dereference the pointer (&string_works) when sending as a parameter, it works. But why? Isn't char * string_broken already a pointer? Why does it need the "extra" dereference when sending as a parameter?)
I'm hoping for a winning answer that explains how you (yes, you) conceptualize sending char * as a parameter vs receiving it as the function's return value.
int get_args_broken(int argc, char **argv, char *string)
{
string = get_string(argc, argv);
printf("in get_args_broken %p string %s\n",string,string);
}
You're only modifying the string local (automatic) variable. That's not visible to the caller in any way. Note that this means you're freeing a wild pointer in main.
It's wrong for the same reason:
int get_sum(int sum, int a, int b)
{
sum = a + b;
}
is; the parameter is copied by value. Also, you're not returning an int (as you declared you would).
int get_args_works(int argc, char **argv, char **string)
{
*string = get_string(argc, argv);
printf("in get_args_works %p string %s\n",*string,*string);
}
is correct (except the missing return). You're not modifying string, which would be pointless. You're modifying the object at the location in string, which in this case is a char *.
EDIT: You would need to triple * the argv if there was a function calling main, and you wanted to set that function's variable to a different char **. E.G.
void trip_main(int *argc, char ***argv)
{
*argc = 10;
*argv = malloc(*argc * sizeof(char *));
}
void caller()
{
char **argv;
int argc;
trip_main(&argc, &argv);
}
One of the needs to use Pointer to a pointer (here get_args_works()) is to modify (or return) more than on variable from a function, as in C it's not possible to return more than one variable.
get_args_works() works 'coz, you are passing pointer to a pointer & a reference to it is there in your main().
But in get_args_broken() you are passing just a pointer. Nothing wrong here, now you do malloc() & return back the memory allocated string to get_args_broken(), still nothing wrong here. But now, this mem allocated string is local & main() does not have a reference to this var. So when you dereference char *string_broken; in main() it might cause undefined behavior.
Hope this's clear.

Resources