C编程将字符数组传递给函数

5

我正在使用一个函数来解析userID、paswd以及进行一些错误检查。该函数从我的main()函数中调用... 但是,当执行时,只有我的UserID和Pswd的前4个字符成功提取。我刚开始学习C编程,来自C#,不确定我错在哪里。这应该相当容易,有人可以指点我正确的方向吗?

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

此外,只是想指出,如果我不使用外部函数,而将所有代码放在我的主函数中,那么它就可以工作。
编辑:找到了问题所在。
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并没有像我预期的那样起作用...它读取了我的指针大小,而默认情况下始终为4个字符。


4
编译器是否提示了警告?如果有,是什么警告?为什么你忽略了这些警告? - Scott Hunter
1
只需在 UserId 和 Psw 前面删去 * 即可。 - Heath Hunnicutt
2
请将你的解决方案从问题中删除。答案放在Stack Overflow的回答框中。 - Jongware
1
做自己一个忙,不要养成使用strcpy()strncpy()等函数的习惯。虽然后者通常被标记为“安全”,但其使用仍有两个主要缺陷:1.它需要字符串长度的上限,2.由于缺少终止符可能会触发缓冲区溢出。相反,请使用分配函数,如getline()strdup()asprintf() - cmaster - reinstate monica
1
@Philo 他的意思是你应该添加一个答案到你的问题中(就好像它是别人的问题一样),而不是编辑问题 ;) - vestlen
显示剩余11条评论
4个回答

3
我猜你的指针大小为4字节。因此你只读取了4个字符。

1

简而言之:

sizeof并不会达到你的预期效果。尝试使用strlen代替。


您只复制了4个字符,因为对于任何N,sizeof(char*[N])都只是指针的大小。在您的平台上,指针必须是4个字节(32位)。
我认为您实际上是想将数组的基地址传递到函数中,但在这种情况下,您的类型不太正确。您的编译器应该会警告您。您应该从最后两个参数类型中删除*
static void func1(int argc, char *argv[], char UserID[30], char Psw[30])

那应该可以消除警告,而且它还应该使sizeof正确运行(因为sizeof(char[30])是30)。但是,使用sizeof很容易犯错误,因为char*char[]的行为是不同的……我更喜欢在这里使用strlen(或者如果你想避免可能的缓冲区溢出,可以使用strnlen),它只会告诉你有多少个非空字符。

使用strnlen而不是sizeof也有助于提示您参数类型错误,因为它会抱怨您试图将char**传递给期望char*的函数。


如果我在代码中直接使用strlen,那么我只能得到userID和Pswd中的数字,其余字符都是以空字符结尾的。另外,需要指出的是,如果我不使用外部函数,而是将所有代码放在我的主函数中,则可以正常工作。 - Philo
正如Scott Hunter在他的评论中指出的那样,您应该在此代码中获得一些编译器警告,因为您存在类型不匹配的问题...如果您修复这些警告,那么它可能会起作用。 - DaoWen

1

将数组大小传递给函数

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

为了保证目标数组以空字符结尾,建议使用strncat() --> "结果总是追加一个终止的空字符。"strncpy()存在太多问题,不一定总是生成以空字符结尾的数组。
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);  
} 

[编辑]

修正代码 - 偏移量为1


-1

解决方案

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

仍然存在同样的问题,只有前4个字符。 - Philo
1
一致的缩进会让这段代码更易于人类阅读。 - user3629249

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接