Copying a char array to another const char array during declaration - c

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'}

Related

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

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)

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

C: Accessing the second argv via a pointer

As I'm quite new to C, there's something I don't yet get about pointers. I'd like to check wether a command line argument is integer or not, but in a separate function, so that I pass in the pointer of the argv array.
int main(int argc, char* argv[]){
if(check(argv)){
// Do stuff to argv[1]
}
}
int check(char* p){
// Test wether p+1 is int
return 1;
}
I have tried several things mostly resulting in weird printf's (when printing the dereferenced pointer to test the value).
int i = atoi(argv[1]);
Works just fine, of course. But as the pointer is the only thing passed to the function, I'm paralysed.
Argv is a two dimensional array, which is to say that argv is an array of arrays. Specifically, argv is an array of char arrays. Now, the data that argv is storing is the arguments passed from the command line to the program, with argv[0] being the actual name of the program and the rest being the arguments.
Now, to answer your question, you need to not pass argv in its entirety to the function "check". What you need to do is pass one of argvs elements. This is because the parameter to "check" is a char array, and argv is an array of char arrays. So try passing argv[1] to check the first argument.
Edit: Try this to check all arguments except the name of the program
#include <stdio.h>
#include <ctype.h>
int main(int argc, char* argv[]) {
for (int i = 1; i < argc; ++i) {
if( check(argv[i]) ){
// Do stuff to argv[i]
}
}
int check(char* p){
int i = 0;
char c = p[i];
while (c != '\0') {
if (!isdigit(c))
return 0;
c = p[++i];
}
return 1;
}
int check(char* p){
The above function expects a pointer to a char while you are passing argv which is array of char *
Try
int check(char* p[]){
Also before using argv[1] check if argv[1] exists ie check argc
int main(int argc, char* argv[]){
if(argc>1 && check(argv)){
// Do stuff to argv[1]
}}
Before indexing an array of pointer, we have to be sure it's valid. We have to use argc to this purpose.
strtol is a function which parse a string and detect error if it's not of the base asked.
Ty this:
int main(int argc, char* argv[]){
if(check(argc, argv)){
// Do stuff to argv[1]
}
}
int check( int argc, char * argv[] ){
if( argc > 1 ) {
char * err = NULL;
strtol( argv[1], &err, 10 );
return argv[1][0] != '\0' && *err != '\0';
}
return 0;
}

C programming passing a char array into a function

I am using a function to parse through userID, and paswd and some error checking. The function is called from my main()... However when executed only the first 4 characters of my UserID and Pswd are successfully extracted. I am new to C-programming and coming from C# I am not sure where I am going wrong. This should be fairly easy, can someone point me in the right direction?
static void func1(int argc, char *argv[], char *UserID[30], char *Psw[30])
{
strncpy(UserID, argv[1], sizeof(UserID));
strncpy(Psw, argv[2], sizeof(Psw));
}
int main(int argc, char *argv[])
{
char UserID[30];
char Psw[30];
func1(argc, argv, UserID, Psw);
}
Also, just to point out, if I don't use the external function, and have all the code in my main func then it works.
EDIT:-
Figured out the issue:-
static void func1(int argc, char *argv[], char *UserID, char *Psw)
{
strncpy(UserID, argv[1], UserIDMaxSize);
strncpy(Psw, argv[2], PswMaxSize);
}
int main(int argc, char *argv[])
{
char UserID[UserIDMaxSize + 1]; /* max val defined in a header file */
char Psw[PswMaxSize + 1]; /* max val defined in a header file */
func1(argc, argv, UserID, Psw);
}
sizeof doesnt work quite as I expected it to.. it was reading the size of my pointer which is always 4 chars by default.
I guess your pointer has a size of 4 Byte. therefore you only read 4 chars.
Pass the array size to the function
static void func1(int argc, char *argv[], char *UserID, size_t UserIDSize,
char *Psw, size_t PswSize)
{
if (argc> 1) strncpy(UserID, argv[1], UserIDSize);
if (argc> 2) strncpy(Psw, argv[2], PswSize);
}
int main(int argc, char *argv[])
{
char UserID[30] = {0};
char Psw[30] = {0};
func1(argc, argv, UserID, sizeof UserID, Psw, sizeof Psw);
}
To insure the destination arrays are null character terminated, suggest strncat() --> "A terminating null character is always appended to the result." strncpy() has too many problems, it does not always result in an array with a null character.
static void func1(int argc, char *argv[], char *UserID, size_t UserIDSize,
char *Psw, size_t PswSize) {
UserId[0] = '\0';
// if (argc> 1) strncat(UserID, argv[1], UserIDSize);
if (argc> 1) strncat(UserID, argv[1], UserIDSize - 1);
Psw[0] = '\0';
// if (argc> 2) strncat(Psw, argv[2], PswSize);
if (argc> 2) strncat(Psw, argv[2], PswSize - 1);
}
[Edit]
Corrected code - off by 1
TL;DR
The sizeof isn't doing what you're expecting. Try using strlen instead.
You're only getting 4 characters copied because sizeof(char*[N]) for any N is just going to be the size of a pointer. On your platform, a pointer must be 4 bytes (32 bits).
I think you actually mean to pass the base-address of the array into the function, but in that case your types aren't quite right. Your compiler should be warning you about this. You should remove the * from your last 2 argument types:
static void func1(int argc, char *argv[], char UserID[30], char Psw[30])
That should get rid of the warning, and it should actually make sizeof behave correctly as well (since sizeof(char[30]) is 30). However, it's very easy to make mistakes with sizeof since the behavior with a char* and char[] are different... I'd prefer using strlen (or strnlen if you want to avoid possible buffer overflows) here instead, which will simply tell you how many non-null characters you have.
Using strnlen rather than sizeof would also help to tip you off that your parameter types are wrong, since it will complain that you're trying to pass a char** to a function that expects a char*.
Solution
#include <stdio.h>
#include <string.h>
void func1(int argc, char *argv[], char *UserID, char *Psw)
{
strncpy(UserID, argv[1], strlen(argv[1]));
strncpy(Psw, argv[2], strlen(argv[2]));
printf("DATA: %s \n",UserID);
printf("DATA1: %s \n",Psw);
}
int main(int argc, char *argv[])
{
char UserID[30];
char Psw[30];
printf("argv1 %ld \n",strlen(argv[1]));
printf("argv2 %ld \n",strlen(argv[2]));
func1(argc, argv, UserID, Psw);
}

Swap char with table pointers in C

I'm trying to swap two char with two table pointers.
Can someone explain to me what's wrong in my code?
The terminal says char** is expected but I don't know what to do, so I think I don't really understand how pointers work for tables.
void echangeM2(char **ptab1, char **ptab2){
char *tmp = *ptab1;
*ptab1 = *ptab2;
*ptab2 = *tmp;
printf("%s\t %s",*ptab1,*ptab2);
return;
}
int main(void) {
char tab1[25];
char tab2[25];
char *adtab1;
char *adtab2;
*adtab1 = &tab1;
*adtab2=&tab2;
printf("type two words");
scanf("%s %s",tab1,tab2);
echangeM2(adtab1,adtab2);
return 0;
}
The following code should work for you:
#include <stdio.h>
void exchangeM2(char* *ptab1, char* *ptab2) { // accepts pointer to char*
char* tmp = *ptab1; // ptab1's "pointed to" is assigned to tmp
*ptab1 = *ptab2; // move ptab2's "pointed to" to ptab1
*ptab2 = tmp; // now move tmp to ptab2
printf("%s\t %s",*ptab1,*ptab2);
}
int main(void) {
char tab1[25];
char tab2[25];
char* adtab1;
char* adtab2;
adtab1 = tab1; // array name itself can be used as pointer
adtab2 = tab2;
printf("type two words");
scanf("%s %s",tab1,tab2);
exchangeM2(&adtab1, &adtab2); // pass the address of the pointers to the function
}
echangeM2(&adtab1,&adtab2);
This should fix the compile errors. You are passing char* pointers to a function that expects a char ** pointer
Edit: Actually looks like you want something like
char **adtab1;
char **adtab2;
adtab1 = &tab1;
adtab2=&tab2;
...
echangeM2(adtab1,adtab2);

Resources