代码之家  ›  专栏  ›  技术社区  ›  John M Gant aman_novice

我可以增加传递给函数的char*吗?

  •  3
  • John M Gant aman_novice  · 技术社区  · 15 年前

    我正在研究一个C++应用程序,它将从一组数据库字段构建固定长度的记录。我正在编写一个函数,它将接受输出记录作为 char* ,要写入的字符串,以及字段的总长度。函数的目的是将字符串复制到char指针的当前位置,然后用空格填充其余长度。下面是我正在做的一个简单的例子。

    void writeOut(char* output, string data, const int length) {
        if ((int) data.size() > length) {
            //Just truncate it
           data = data.substr(0, length);
        }
        int index = 0;
        while (index < (int) data.size()) {
            *output++ = data[index++];
        }
        while (index++ < length) {
            *output++ = ' ';
        }
    }
    
    int test() {
        char output[100];
        writeOut(output, "test1", 10);
        writeOut(output, "test2", 10);
        writeOut(output, "test3test4test5", 10);
        cout << output;
    }
    

    我想看到这样的东西。

    test1     test2     test3test4                  
    

    相反,我得到的只是…

    test3test4
    

    所以它增加了 烧焦* 在函数内,但仅在函数内。当函数结束时 烧焦* 就在它开始的地方。是否可以以调用函数中更新指针的方式传递指针?

    万一你说不出来,我对C++很陌生。如有任何建议,我们将不胜感激。

    7 回复  |  直到 15 年前
        1
  •  8
  •   Steve Guidi    15 年前

    由于不通过引用传递参数,编译器将创建指针的副本,并在函数中相应地修改副本。

    将函数签名更改为以下内容。

    void writeOut(char*& output, string data, const int length)
    

    你也可以考虑传球 string 作为 const string& 如果你不打算修改它。

        2
  •  8
  •   developmentalinsanity    15 年前

    您想将char**传递给函数。

    void writeOut(char** output, string data, const int length) {
        if ((int) data.size() > length) {
            //Just truncate it
           data = data.substr(0, length);
        }
        int index = 0;
        while (index < (int) data.size()) {
            *(*output)++ = data[index++];
        }
        while (index++ < length) {
            *(*output)++ = ' ';
        }
    }
    
    int test() {
        char output[100];
        char *pos = output;
        writeOut(&pos, "test1", 10);
        writeOut(&pos, "test2", 10);
        writeOut(&pos, "test3test4test5", 10);
        cout << output;
    }
    

    (手头没有编译器,但是这个 应该 工作)

        3
  •  6
  •   Reed Copsey    15 年前

    您可以通过保留一个新的字符指针来完成您要完成的任务,但不能增加“输出”变量,然后 再次使用它 (在你的行里)不加修饰的。

    例如,您可以执行以下操作:

    char* writeOut(char* output, string data, const int length) {
        if ((int) data.size() > length) {
            //Just truncate it
           data = data.substr(0, length);
        }
        int index = 0;
        while (index < (int) data.size()) {
            *output++ = data[index++];
        }
        while (index++ < length) {
            *output++ = ' ';
        }
        return output; // return the new position here!
    }
    
    int test() {
        char output[100];
        char *outputLocation = output;
        outputLocation = writeOut(outputLocation, "test1", 10);
        outputLocation = writeOut(outputLocation, "test2", 10);
        outputLocation = writeOut(outputLocation, "test3test4test5", 10);
        cout << output;
    }
    
        4
  •  2
  •   Richard Corden    15 年前

    现在的情况是,每次你打电话时,你都会把相同的位置(即开始)传给对方。

    您需要的是另一个变量,当您调用writeout时,该变量会随之移动。有几种方法可以做到这一点:

    第一个也是“最简单”的选项是使您传递的参数成为“指针引用”:

    void writeOut (char *& output, ...) {
       // ...
    }
    
    int test () {
      char output[100];
      char * p = output;
      writeOut (p, "test1", 10);
      writeOut (p, "test2", 10);
      // ...
    }
    

    这是因为参数 output 现在是指针的别名 p 在主体中。因此,在writeout中对参数所做的更改也会发生在 P .

    下一个最简单的选择是每次返回新位置:

    char * writeOut (char * output, ...) {
       // ...
    
    
       return output;
    }
    
    int test () {
      char output[100];
      char * p = output;
      p = writeOut (p, "test1", 10);
      p = writeOut (p, "test2", 10);
      // ...
    }
    

    这里,参数在函数内部被修改,我们更新 每次主要。

    最后,您可以使参数写一个指向指针的指针:

    void writeOut (char ** output, ...) {
       // ...
    
       while (index < (int) data.size()) {
         **output = data[index++];
         (*output)++;
       }
    
       // ...
    }
    
    int test () {
      char output[100];
      char * p = output;
      writeOut (&p, "test1", 10);
      writeOut (&p, "test2", 10);
      // ...
    }
    

    这里所发生的是,我们的参数不再指向“output”,而是指向“p”的地址。在我考虑这个问题之前,我几乎肯定会选择引用选项。

        5
  •  0
  •   Brian Liang    15 年前

    你需要通过参考。

        6
  •  0
  •   Douglas Leeder    15 年前

    要理解的重要一点是,函数的参数是通过值传递的,也就是说,它们是被复制的。

    函数的第一个参数是指针,换句话说就是指向内存的数字。当您调用函数时,这个数字是从 test() printOut() ,允许 打印输出() 以访问 测试() 分配。

    正如其他人所建议的,您可以返回指针的新值,也可以将其作为引用传入。或者,您可以使用指向指针的指针,该指针允许您在 打印输出() .

        7
  •  0
  •   Carl Norum    15 年前

    为什么不直接用snprintf?

    int writeOut(char *output, char *data, int length)
    {
      return snprintf(output, length + 1, "%-*s", length, data);
    }
    
    void test()
    {
      char output[100];
      char *outputLocation = output;
      outputLocation += writeOut(outputLocation, "test1", 10);
      outputLocation += writeOut(outputLocation, "test2", 10);
      outputLocation += writeOut(outputLocation, "test3test4test5", 10);
      printf("%s\n", output);
    }
    

    我觉得这比较容易。我想由你决定吧。