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 调用.