【问题标题】:how to get multiple variables from function without struct?如何从没有结构的函数中获取多个变量?
【发布时间】:2021-07-25 20:08:32
【问题描述】:

我正在为大学时的一项任务编写代码,我已经编写了大部分代码,但我刚刚意识到我的核心功能中的某些东西并没有像我希望的那样工作。我尝试多次对其进行故障排除,但我不明白为什么我的 char 变量在运行结束时被删除,而 int 变量仍然存在。

void  Analyze() 
{
    char buffer[81];
    char* ptr;
    char* ptr2;
    ptr = 0;
    fgets(buffer, sizeof buffer, stdin);
    printf("%s\n", buffer);
    char* command = strtok_s(buffer, " \t", &ptr);
    printf_s("the command you selcted is %s\n", command);
    char* Matname = strtok_s(NULL, " \t", &ptr);
    printf_s("the name you selcted is %s\n", Matname);
    char* row1 = strtok_s(NULL, "  \t", &ptr);
    printf_s("the rowsize you selcted is %s\n", row1);
    char* col1 = strtok_s(NULL, " \t", &ptr);
    printf_s("the colsize you selcted is %s\n", col1);
    row = strtol(row1, &ptr2, 10);
    col = strtol(col1, &ptr2, 10);
     //  *command = command;
      // *Matname = Matname;
    printf_s("row number is %d, col number is %d", row, col);
    return ;
 }

我需要得到command 名称和Matname,所以在那之后我不知道如何将它分配给矩阵。现在,由于某种原因,我只得到了 row 和 col,我可以用它构建一个矩阵。

就像我说的,这是我项目中的主要功能,最后所有的文本都不是用于调试的,我似乎不知道为什么commandMatname被删除了。

【问题讨论】:

  • 你熟悉函数参数的概念吗?
  • 范围变量和函数参数在任何初级C编程书籍中都有介绍。 SO 不能替代传统研究。
  • 永远不要使用全局变量,你应该为自己省去很多痛苦。
  • 我之前评论的重点是您通过编辑和修复问题来澄清问题,而不是添加评论。所有关于变量是否被删除的东西都是无稽之谈,在任何情况下都与您的问题无关。发布一个您需要帮助理解的新问题。
  • @lulle - 完全正确,尽管您应该避免在 cmets 中回答问题。如果您有答案,请发布答案。

标签: arrays c function matrix char


【解决方案1】:

调用者应该提供缓冲区来接收字符串,将缓冲区传递给函数,因此:

void Analyse( char* cmd_buffer, size__t cmd_len, 
              char* matname_buffer, size_t matname_len ) ;

int main()
{
    char* command[81] = {0} ;
    char* matname[81] = {0} ;

    Analyse( command, sizeof(command) - 1, 
             matname, sizeof(matname) - 1 ) ;
}


void Analyse( char* cmd_buffer, size__t cmd_len, 
              char* matname_buffer, size_t matname_len )
{
    ...

    strncpy( cmd_buffer, command, cmd_len ) ;
    strncpy( matname_buffer, Matname, matname_len ) ;

    return ;
}

【讨论】:

    【解决方案2】:

    在 C 中,函数不能返回多个值。你基本上有两种选择:

    • 将缓冲区传递给函数,用相关数据填充提供的缓冲区(请参阅 Clifford 的回答)。
    • 在函数中分配缓冲区并返回指向该缓冲区的指针。

    对于后者,你可以这样做:

    void foo(char **p_cmd_buffer, char ** p_matname_buffer){
        ...
        *p_cmd_buffer = malloc(cmd_buffer_required_size);
        if(p_cmd_buffer != NULL){
            //copy your data to the buffer
        }
        *p_matname_buffer = malloc(cmd_buffer_required_size);
        if(p_matname_buffer != NULL){
            //copy your data to the buffer
        }
        ...
    }
    
    int main(void){enter code here
        ...
        char *cmd, *matname;
        foo(&cmd, &matname);
        ...
    }
    

    或者,您可以将数据包装在一个结构中,在您的函数中分配一个,填充它并返回一个指向它的指针:

    struct wrapper_struct{
        char *matname;
        char *cmd;
    }
    
    struct wrapper_struct* foo(void){
        ...
        struct wrapper_struct* ret = malloc(sizeof(struct wrapper_struct));
        if(ret != NULL){
            ret->cmd = malloc(cmd_buffer_required_size);
            if(ret->cmd != NULL){
                //copy your data to the buffer
            }
            ret->matname = malloc(matname_buffer_required_size);
            if(ret->matname){
                //copy your data to the buffer
            }
        }
    } 
    
    int main(void){
        ...
        wrapper_struct* data = foo();
        ...
    }
    

    这只有在调用函数不知道缓冲区必须有多大的情况下才真正有用。在您的情况下,大小是已知的(每个字符串 81 个字符)。

    缺点:

    • 调用函数可能不知道内存是如何分配的。您必须提供额外的功能才能再次释放数据。
    • 您必须处理分配内存的潜在失败

    【讨论】:

      猜你喜欢
      • 2019-10-31
      • 2022-10-23
      • 1970-01-01
      • 2016-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-18
      相关资源
      最近更新 更多