C函数将argv内容检索到字符串

问题描述

我没有时间以任何方式提交我的解决方案,但我很沮丧。

我正在编写一个函数,该函数将在执行时使用 argv 并将其内容连接到一个字符串中,并使用由 \n 分隔的命令 像这样的东西"./a.out \n a \n b \n c \n ..etc"

这是 m 代码(它不起作用):

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char *my_concat_params(int argc,char **argv){
    char argss[argc];
    
    for (int i = 0; i<argc;i++){
        strcpy(argss[i],argv[i]);
    }
        return argss[0];
    }


int main(int argc,char **argv){
    //char *cmdlne = my_concat_params(argc,argv);
    printf("%d,%s\n",argc,argv[argc-1]);
    return 0;
}

通过指向 pinter 进行导航并返回我想要的字符串的正确方法是什么?

解决方法

argss 在堆栈中,因此您无法返回它。

您需要使用 char * 来增加长度的 realloc

这里有一些代码[为清楚起见,我使用 | 作为分隔符而不是 \n]:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void *
xrealloc(void *buf,size_t len)
{

    buf = realloc(buf,len);

    if (buf == NULL) {
        perror("realloc");
        exit(1);
    }

    return buf;
}

// RETURNS: pointer to concatenated string
char *
my_concat_params(int argc,char **argv)
{
    char *buf = NULL;
    int dstlen = 0;
    char *src;
    int srclen;
    int seplen = 0;

    // process all arguments
    for (;  argc > 0;  --argc,++argv) {
        // point to current argument
        src = *argv;

        // get its length
        srclen = strlen(src);

        // grow the output buffer:
        // output length + space for separator + arg length + space for EOS
        buf = xrealloc(buf,dstlen + seplen + srclen + 1);

        // add the separator [for _subsequent_ arguments]
        if (seplen)
            buf[dstlen++] = '|';
        seplen = 1;

        // append the current argument
        strcpy(&buf[dstlen],src);

        // increase output length to account for current argument
        dstlen += srclen;
    }

    // add EOS string terminator
    buf[dstlen] = 0;

    return buf;
}

int
main(int argc,char **argv)
{
    char *cmdlne = my_concat_params(argc,argv);

    //printf("%d,%s\n",argc,argv[argc - 1]);
    printf("%s\n",cmdlne);

    free(cmdlne);

    return 0;
}

对于调用:

./fix1 abc def hello world

输出为:

./fix1|abc|def|hello|world
,

您不能从函数返回堆栈分配的空间。这样做会导致意想不到的结果,其中立即崩溃可能是最好的结果。

您最好的做法是在堆上动态分配内存以存储您的结果。

示例:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#ifdef MCCP_MIN_GROW_BY
# error "The name MCCP_MIN_GROW_BY already used,pick a different name"
#endif
#define MCCP_MIN_GROW_BY (128) // pick a value that matches best your expected input 
                               // and available resources.

char *my_concat_params(int argc,const char **argv)
{
    int available_bytes = 0;
    int next_length     = 0;
    int allocated_bytes = 0;
    int bytes_to_add    = 0;

    char* result        = NULL;
    char* current_pos   = NULL;
    char* temp          = NULL;

    result = (char*)malloc(MCCP_MIN_GROW_BY);
    if (!result)
       return NULL;

    *result = 0;   // takes care of the case argc == 0

    current_pos = result;
    available_bytes = MCCP_MIN_GROW_BY;

    while (argc--) 
    {
        // append the next argument to the result,allocating space as needed.
        next_length = strlen(*argv);

        if (available_bytes < next_length + 2)  // '\n' + '\0'
        {
            bytes_to_add = ((next_length + 2) < MCCP_MIN_GROW_BY) 
                             ? MCCP_MIN_GROW_BY
                             : next_length + 2;
            
            // when using realloc,do not lose your original pointer
            // so you can at least free resources gracefully in case 
            // of an error.
            temp = (char*)realloc(result,allocated_bytes + bytes_to_add);
            if (temp == NULL)
            {
                free(result);
                return NULL;
            }
            available_bytes += bytes_to_add;
        }

        memcpy(current_pos,*argv,next_length);  // add the string
        current_pos += next_length;

        *current_pos++  = '\n';                    // the line feed
        *current_pos    = 0;                       // and terminate
        available_bytes -= next_length + 1;        // keep track of space left
        ++argv;
    }
    return result;
}
#undef MCCP_MIN_GROW_BY


int main(int argc,const char **argv)
{
    char *cmdlne = my_concat_params(argc,argv);

    printf("%d,cmdlne);

    free(cmdlne);

    return 0;
}