如何在方法中复制字符串?

时间:2011-10-31 07:17:44

标签: c string pointers return local

问题: 现在我得到一个源字符串,我将从中获取一个子字符串,但不会破坏它,因为源字符串在未来使用。

TEST.CPP:

void method1(source,char* result)
{
   char temp[num];
   strcpy(temp,source); //copy the source string
   ...         //use temp
   result=target string;
}
void method2(source,char* result)
{
   char temp[num];
   strcpy(temp,source); //copy the source string
   ...         //use temp
   result=target string;
}
int main()
{
   char source[];
   ...(maybe I declare some variables to save the result,e.g. char* result)
   method1(source,result);
   method2(source,result);
}

这不起作用,因为方法中的复制变量'temp'将在重新调用之前被销毁。 我有一个有效的版本: 作者使用结构来保存结果:

typedef struct
{
   char* sub[50];
   uint32_t num;
}result_t;

它适用于两个单独的文件:

desc_data_parser.h:

#ifndef _DESC_DATA_PARSER_H_
#define _DESC_DATA_PARSER_H_
#include <stdint.h>

class desc_data_parser
{
    public:

        static const uint32_t MAX_DESC_DATA_NUM=512;
        typedef struct
        {
            char* desc_result[MAX_DESC_DATA_NUM];
            uint32_t desc_result_num;
        }desc_result_t;

    public:

        static int lookup_value(char* source,char* key, desc_result_t* results);
        static int lookup_value_t(char* source,char* key, char* results);
};
#endif

desc_data_parser.cpp:

#ifndef _DESC_DATA_PARSER_
#define _DESC_DATA_PARSER_
#include "desc_data_parser.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>


int desc_data_parser::lookup_value(char* source, char* key, desc_result_t* results)
{
    printf("yourself\n");
    if((NULL == source) || ('\0' ==source[0]) || (NULL == key) || ('\0' == key[0]))
        return 0;
    int num = 0;
    //bzero(results,sizeof(desc_result_t));
    char copy_buf[2046]; //the source buf
    char* t_buf;
    strcpy(copy_buf,source);
    t_buf = copy_buf;
    //t_buf = strstr(t_buf,key); //keep the buf with key
     results->desc_result[0]=copy_buf;


    return num;

}
int desc_data_parser::lookup_value_t(char* source, char* key, char* results)
{
    printf("yourself\n");
    if((NULL == source) || ('\0' ==source[0]) || (NULL == key) || ('\0' == key[0]))
        return 0;
    int num = 0;
    char copy_buf[2046]; //the source buf
    char* t_buf;
    strcpy(copy_buf,source);
    t_buf = copy_buf;

     results=copy_buf;


    return num;

}
#endif

测试2.cpp:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "desc_data_parser.h"
using namespace std;

int main() {

  char* source="prod:fdafadfa";
  desc_data_parser::desc_result_t temp_result;
  memset(&temp_result,0,sizeof(desc_data_parser::desc_result_t));
  desc_data_parser::lookup_value(source, "prod:",&temp_result);
  printf("%s last result\n",temp_result.desc_result[0]); //why it works
  char result[50];
  desc_data_parser::lookup_value_t(source, "prod:",result);// why it not
  printf("%s last result\n",result);

}

我试图将test.cpp和test1.cpp合并在一起,但是它不起作用。

我有两个问题:

  1. 为什么上述方法有效?
  2. 本地定义的静态方法和包含的静态方法之间有什么区别吗?
  3. 我更新了帖子以及为什么这两个来电者得到了不同的结果?

3 个答案:

答案 0 :(得分:1)

如果您使用的是C ++,请改用std :: string。

static void method2(source,result_t* result)

这甚至不会编译,源的类型是什么?

答案 1 :(得分:1)

就像您将源代码复制到temp变量一样,您将目标字符串复制到result。在调用函数之前,请记住为result字符串分配足够的空间。

另请注意,将source复制到temp就像你做的那样很糟糕并且非常容易出错,因为source中的字符串可能比为{{temp分配的内存更长1}}。更好的实现可能是这样的:

void method1(source,char* result, size_t result_max)
{
    char *temp = malloc(strlen(source) + 1);  /* +1 for the string terminator */
    strcpy(temp,source); //copy the source string
    ...         //use temp
    strncpy(result, <whatever>, result_max);
    free(temp);
}

与其他功能类似。

答案 2 :(得分:0)

它与分割源文件没有任何关系。当你将char []声明为main函数中的local(在你的示例中作为struct的一部分,但不是必需的)时,它在主函数的持续时间内被分配在堆栈中,其中包括两个调用的两个方法。在方法中使用临时数组时,该方法在方法结束时超出范围。为了使您的方法能够传回数据,它们需要将它存储在函数调用之前分配的内存中,或者需要使用malloc或new在堆上分配内存并返回指向该内存的指针。如果他们确实分配了内存,那么你必须确保它在以后被释放或删除。

自网站未能提交评论以来对您的跟进的回复

编译器不会“清理”有问题的内存,但它会移动堆栈帧,并且数据将在下一个方法调用时被覆盖。它超出范围后访问此内存是未定义的行为,因为您非常喜欢破坏堆栈并最终导致程序崩溃。