5

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.

16
  • 4
    Did the compiler give you any warnings, what were they, and why did you ignore them? Commented Apr 11, 2016 at 20:12
  • 1
    Just take out the * before UserId and Psw. Commented Apr 11, 2016 at 20:24
  • 2
    Please remove your solution from the question. Answers go in an Answer box on Stack Overflow. Commented Apr 11, 2016 at 20:47
  • 1
    Do yourself a favor and don't even get into the habit of using functions like strcpy() or strncpy(). While the later is often labeled as "safe", its use still has two major pitfalls: 1. it requires an upper limit on the length of the string, and 2. it may trigger buffer overruns due to missing termination. Use allocating functions like getline(), strdup(), and asprintf() instead. Commented Apr 11, 2016 at 20:56
  • 1
    @Philo He's saying you should add an answer to your question (as if it were someone else's) instead of editing the question ;) Commented Apr 11, 2016 at 21:33

4 Answers 4

3

I guess your pointer has a size of 4 Byte. therefore you only read 4 chars.

Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

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*.

2 Comments

If I use strlen as it is in the code, then I only get the numbers in my userID and Pswd, the rest of the characters are null-terminated....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.
As Scott Hunter pointed out in his comment, you should be getting some compiler warnings with this code because you have a type mismatch... If you fix those warnings then it'd probably work.
-1

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);
}

2 Comments

still the same problem, only the first 4 characters
consistent indenting would make this code much more readable by us humans.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.