在C中通过引用传递字符串

Jen*_*nna 8 c string pass-by-reference

我无法弄清楚如何通过函数的参数传回字符串.我是编程新手,所以我想这可能是一个初学者的问题.你能给予的任何帮助都将非常感激.这段代码出错了,我不知道为什么,但是我提供的代码来展示我到目前为止所拥有的内容.

我已将其设为社区维基,因此请随意编辑.

PS这不是功课.

这是原始版本

#include <stdio.h>

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

void
fn(char *baz, char *foo, char *bar)
{
     char *pch;

     /* this is the part I'm having trouble with */

     pch = strtok (baz, ":");
     foo = malloc(strlen(pch));
     strcpy(foo, pch);

     pch = strtok (NULL, ":");
     bar = malloc(strlen(pch));
     strcpy(bar, pch);

     return;
}

int
main(void)
{
     char *mybaz, *myfoo, *mybar;

     mybaz = "hello:world";

     fn(mybaz, myfoo, mybar);

     fprintf(stderr, "%s %s", myfoo, mybar);
}
Run Code Online (Sandbox Code Playgroud)

更新这是一个更新版本,其中包含一些建议:

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

#define MAXLINE         1024

void
fn(char *baz, char **foo, char **bar)
{
     char line[MAXLINE];
     char *pch;

     strcpy(line, baz);

     pch = strtok (line, ":");
     *foo = (char *)malloc(strlen(pch)+1);
     (*foo)[strlen(pch)] = '\n';
     strcpy(*foo, pch);

     pch = strtok (NULL, ":");
     *bar = (char *)malloc(strlen(pch)+1);
     (*bar)[strlen(pch)] = '\n';
     strcpy(*bar, pch);

     return;
}

int
main(void)
{
     char *mybaz, *myfoo, *mybar;

     mybaz = "hello:world";

     fn(mybaz, &myfoo, &mybar);

     fprintf(stderr, "%s %s", myfoo, mybar);

     free(myfoo);
     free(mybar);
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*sop 10

首先,那些malloc应该是strlen(whatever)+1字节.C字符串有一个0字符来表示结尾,称为NUL终结符,并且它不包含在由strlen测量的长度中.

接下来,strtok修改你正在搜索的字符串.您正在向它传递一个指向您不允许修改的字符串的指针(您无法修改文字字符串).这可能是段错误的原因.因此,您可以将其复制到您自己的可修改缓冲区,而不是使用指向不可修改的字符串文字的指针,如下所示:

char mybaz[] = "hello:world";
Run Code Online (Sandbox Code Playgroud)

这样做是在堆栈上放置一个12字符大小的数组,并将字符串文字的字节复制到该数组中.它的工作原理是因为编译器在编译时知道字符串的长度,并且可以相应地创建空间.这节省了使用malloc用于该特定副本.

你引用的问题是你正在将mybaz,myfoo和mybar 的传递给你的函数.除非您将指针传递给myfoo和mybar,否则无法修改调用者的变量.由于myfoo是一个char*,指向它的指针是一个char**:

void
fn(char *baz, char **foo, char **bar) // take pointers-to-pointers

*foo = malloc(...);  // set the value pointed to by foo

fn(mybaz, &myfoo, &mybar);  // pass pointers to myfoo and mybar
Run Code Online (Sandbox Code Playgroud)

在代码中修改函数中的foo绝对没有任何影响myfoo.myfoo是未初始化的,所以如果前两个都没有引起它,那么当您使用未初始化的指针进行打印时,很可能会发生段错误.

一旦你基本上工作了,你可能想要添加一些错误处理.strtok如果找不到它正在查找的分隔符,则可以返回NULL,并且不能strlen使用NULL 调用.malloc如果内存不足,则可以返回NULL,也不能strcpy使用NULL 调用.