【问题标题】:C programming passing a char array into a functionC编程将char数组传递给函数
【发布时间】:2017-07-13 23:50:18
【问题描述】:

我正在使用一个函数来解析用户 ID、密码和一些错误检查。该函数是从我的 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);
}

另外,需要指出的是,如果我不使用外部函数,并且将所有代码都放在我的 main 函数中,那么它就可以工作。

编辑:-

找出问题所在:-

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 个字符。

【问题讨论】:

  • 编译器有没有给你任何警告,它们是什么,你为什么忽略它们?
  • 把UserId和Psw前面的*去掉就行了
  • 请从问题中删除您的解决方案。答案在 Stack Overflow 上的 Answer 框中。
  • 帮自己一个忙,甚至不要养成使用strcpy()strncpy()之类的功能的习惯。虽然后者通常被标记为“安全”,但它的使用仍然存在两个主要缺陷:1. 它需要字符串长度的上限,以及 2. 它可能由于缺少终止而触发缓冲区溢出。请改用 getline()strdup()asprintf() 等分配函数。
  • @Philo 他说你应该为你的问题添加一个答案(就好像它是其他人的一样)而不是编辑问题;)

标签: c


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    将数组大小传递给函数

    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

    【讨论】:

      【解决方案3】:

      TL;DR

      sizeof 没有达到您的预期。尝试改用strlen


      您只复制了 4 个字符,因为任何 Nsizeof(char*[N]) 都将是指针的大小。在您的平台上,指针必须是 4 字节(32 位)。

      我认为您实际上的意思是将数组的基地址传递给函数,但在这种情况下,您的类型并不完全正确。你的编译器应该警告你这一点。您应该从最后 2 个参数类型中删除 *

      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 中的数字,其余字符以空字符结尾....另外,只是要指出,如果我不使用外部函数,并且在我的主函数中包含所有代码,那么它可以工作。
      • 正如 Scott Hunter 在他的评论中指出的那样,由于类型不匹配,您应该会收到一些编译器警告,因为您有类型不匹配...如果您修复了这些警告,那么它可能会起作用。跨度>
      【解决方案4】:

      解决方案

      #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个字符
      • 一致的缩进会让我们人类更容易阅读这段代码。
      猜你喜欢
      • 1970-01-01
      • 2012-07-26
      • 2012-05-10
      • 1970-01-01
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多