Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使Char指针成为C中的out参数_C_Pointers - Fatal编程技术网

使Char指针成为C中的out参数

使Char指针成为C中的out参数,c,pointers,C,Pointers,我正在尝试编写一个反转字符串的函数。基本算法可以工作,但我无法在单元测试中影响调用时传递的输入参数。我不相信这是重复的,因为我遇到了新的问题 strings\u test.c char *test_reverse_string() { char rv1[512]; // these are not changing below but should char rv2[512]; // (yet the first test is passing just length is

我正在尝试编写一个反转字符串的函数。基本算法可以工作,但我无法在单元测试中影响调用时传递的输入参数。我不相信这是重复的,因为我遇到了新的问题

strings\u test.c

char *test_reverse_string()
{
    char rv1[512];  // these are not changing below but should
    char rv2[512];  // (yet the first test is passing just length is failing)
    char str1[] = "hello world";
    char str2[] = "a man a plan a canal panama";

    mu_assert(check_strings(reverse_string(rv1, str1), "dlrow olleh") == 0, "Your reverse_string function did not correctly reverse a string.");
    reverse_string(rv1, str1);
    printf(":::::%s:::::;;;;;%i;;;;;", rv1, strlen(rv1)); // I added this line for debugging. It alerted me to fact it wasn't being copied

// This next is the first test that fails 
        mu_assert(strlen(rv1) == 11, "Your reversed string does not have the same length as the original string.");
        mu_assert(check_strings(reverse_string(rv2, str2), "amanap lanac a nalp a nam a") == 0, "Your reverse_string function did not correctly reverse a string.");
        mu_assert(strlen(rv2) == 27, "Your reversed string does not have the same length as the original string.");
    
        return NULL;
    }
通过运行printf(),我注意到rv1和rv2保持为空。我相信这是因为调用函数时,堆栈上正在进行复制,我必须创建指向指针的指针,我已经尝试过了,但这会给我带来错误。我一直在努力实施这一建议

函数定义是按原样提供给我们的,但我相应地修改了它们(使用额外的asterix)。我不知道他们希望学生采取什么方法。我的方法可能不同,也更复杂,但我相信它应该可以很好地工作。顺便说一句,这是一个编码营模块的存档课程,我也已经毕业了,如果可能的话,我想坚持我的攻击路线,因此我在这里而不是那里

我的代码:

字符串

#ifndef strings_h
#define strings_h

int string_length(char s[]);

char *reverse_string(char rv[], char s[]);

#endif
字符串

char *reverse_string(char **rv, char *s) // Note this definition was given, but with only one '*' next to rv. I added second
{
    int length = string_length(s);
    int temp;
    *rv = s;  // I likewise added all the *'s here and below

    for (int g = 0; g < length / 2; g++)
    {
        temp = *rv[length - g - 1];
        *rv[length - g - 1] = *rv[g];
        *rv[g] = temp;
        // s[length] = "\0";
    }
    return s; // have to return this. Returning rv is wrong type. Return doesn't matter
}
我得到了一个分段错误(核心转储),我在上面读到了,这就是我被卡住的地方

PS我试着用一个参考来代替,正如建议的那样

char *reverse_string(char *&rv, char *s) 
但我明白了

error: expected ‘;’, ‘,’ or ‘)’ before ‘&’ token
编辑:我在程序中找到了另一个人,他的测试通过了。我不知道为什么他的作品和我的不一样。当我运行Make和/strings时,我的工作正常,但当我运行“Make测试”时就不工作了。换句话说,我在调试时得到了预期的结果,但当我在测试中实际运行它时,它失败了。我是新手,这种测试方式让我困惑。我还是不知道到底发生了什么。我在输出日志中看到了一个混乱的来源,它给出了一些误导性的数据

这是另一个人的函数的完整输出,该函数工作并通过

tests/strings_tests.c:26:31: warning: format ‘%i’ expects argument of type ‘int’, but argument 3 has type ‘size_t’ {aka ‘long unsigned int’} [-Wformat=]
   26 |     printf(":::::%s:::::;;;;;%i;;;;;", rv1, strlen(rv1));
      |                              ~^             ~~~~~~~~~~~
      |                               |             |
      |                               int           size_t {aka long unsigned int}
      |                              %li
In file included from tests/strings_tests.c:2:
tests/strings_tests.c: In function ‘main’:
tests/../../utils/minunit.h:17:38: warning: parameter ‘argc’ set but not used [-Wunused-but-set-parameter]
   17 | #define RUN_TESTS(name) int main(int argc, char *argv[]) {\
      |                                  ~~~~^~~~
tests/strings_tests.c:44:1: note: in expansion of macro ‘RUN_TESTS’
   44 | RUN_TESTS(all_tests);
      | ^~~~~~~~~
sh ./tests/runtests.sh
Running unit tests:
-----
RUNNING: ./tests/strings_tests
:::::dlrow olleh:::::;;;;;11;;;;;ALL TESTS PASSED
Tests run: 2
tests/strings_tests PASS
注意第一行printf(第三行)。我加了这个。这会抛出一个错误,但同一行在下面,测试通过。我将printf行插入测试文件以进行调试,因为测试失败时它会中止,我想看看是否出现了问题。当我运行代码时,它因此中止。我看他也有同样的空行:换句话说,因为我不知道怎么读这个,所以我得到了一个假阴性,或者被引入了错误的轨道。这篇文章和另一篇文章讨论了如何为输出参数设置一个指向指针的指针,所以它非常有意义,但现在已经没有了

至于我的算法失败的原因,我不确定,因为当我运行main时,它在我的make文件中工作。我看到的唯一区别是他用他们说的那样的“/0”来终止字符串,但我认为在适当的位置更改它会保留该字符。当我试图手动添加它时,我总是会出错。我很困惑为什么它讨厌我的做事方式

// Tests pass on this copied algorithm
char *reverse_string(char *rv, char *s)
{

    int rslength = string_length(s);
    int index = 0;

    for (int i = rslength - 1; i >=0; i--) {
      rv[index] = s[i];
      index = index + 1;
    }
    rv[index] = '\0';
    return rv;

}

//tests fail. properly reverses string but doesn't get right length
char *reverse_string(char *rv, char *s) 
{
    int length = string_length(s);
    int temp;
    (rv) = s;
    int g;

    for (g = 0; g < (length / 2); g++)
    {
        temp = (rv)[length - g - 1];
        (rv)[length - g - 1] = (rv)[g];
        (rv)[g] = temp;

    }
    // rv[length] = '\0';  // Whether I add this line or not I get the error below 
    return rv;
}
//测试通过了这个复制的算法
字符*反向_字符串(字符*rv,字符*s)
{
int rslength=字符串长度;
int指数=0;
对于(int i=rslength-1;i>=0;i--){
rv[index]=s[i];
指数=指数+1;
}
rv[索引]='\0';
返回rv;
}
//测试失败。正确反转字符串,但长度不正确
字符*反向_字符串(字符*rv,字符*s)
{
整数长度=字符串长度;
内部温度;
(rv)=s;
int g;
对于(g=0;g<(长度/2);g++)
{
温度=(rv)[长度-g-1];
(rv)[长度-g-1]=(rv)[g];
(rv)[g]=温度;
}
//rv[length]='\0';//无论我是否添加这一行,我都会得到下面的错误
返回rv;
}
错误

[错误](tests/strings\u tests.c:27:errno:None)反向字符串的长度与原始字符串的长度不同。
make:**[../mainbuild.mk:47:tests2]错误1

//我添加了第二个
为什么?输出缓冲区
rv
作为参数接收,您不需要(在这种情况下您不能)更改它。.您所有的
*rv[i]
尊敬都缺少所需的括号。将它们全部更改为
(*rv)[i]
。但是为什么您同时拥有
rv
s
?这是没有意义的,因为字符串是在原地反转的。另外,当它需要一个
char**
时,您正在为
rv
传递一个
char*
。可以按当前声明的方式使用它的唯一方法是传递指针变量的地址。但是如前所述,您只需要删除
rv
参数,因为它没有任何用途。我有rv参数,因为我们得到了函数定义,它符合单元测试和头文件。除了访问原始指针,我不想更改参数。单元测试不接受返回值。它想改变它的输入参数。这就是为什么我认为我需要一个*或者也许是一个-,但基本上我把事情都留给了他们。我用上面更多的信息做了一些编辑。根据一些错误或误读的线索,我认为我走错了方向。我还是不明白为什么会出现长度错误。调试正确时的输出。
tests/strings_tests.c:26:31: warning: format ‘%i’ expects argument of type ‘int’, but argument 3 has type ‘size_t’ {aka ‘long unsigned int’} [-Wformat=]
   26 |     printf(":::::%s:::::;;;;;%i;;;;;", rv1, strlen(rv1));
      |                              ~^             ~~~~~~~~~~~
      |                               |             |
      |                               int           size_t {aka long unsigned int}
      |                              %li
In file included from tests/strings_tests.c:2:
tests/strings_tests.c: In function ‘main’:
tests/../../utils/minunit.h:17:38: warning: parameter ‘argc’ set but not used [-Wunused-but-set-parameter]
   17 | #define RUN_TESTS(name) int main(int argc, char *argv[]) {\
      |                                  ~~~~^~~~
tests/strings_tests.c:44:1: note: in expansion of macro ‘RUN_TESTS’
   44 | RUN_TESTS(all_tests);
      | ^~~~~~~~~
sh ./tests/runtests.sh
Running unit tests:
-----
RUNNING: ./tests/strings_tests
:::::dlrow olleh:::::;;;;;11;;;;;ALL TESTS PASSED
Tests run: 2
tests/strings_tests PASS
// Tests pass on this copied algorithm
char *reverse_string(char *rv, char *s)
{

    int rslength = string_length(s);
    int index = 0;

    for (int i = rslength - 1; i >=0; i--) {
      rv[index] = s[i];
      index = index + 1;
    }
    rv[index] = '\0';
    return rv;

}

//tests fail. properly reverses string but doesn't get right length
char *reverse_string(char *rv, char *s) 
{
    int length = string_length(s);
    int temp;
    (rv) = s;
    int g;

    for (g = 0; g < (length / 2); g++)
    {
        temp = (rv)[length - g - 1];
        (rv)[length - g - 1] = (rv)[g];
        (rv)[g] = temp;

    }
    // rv[length] = '\0';  // Whether I add this line or not I get the error below 
    return rv;
}