将字符串数组作为参数传递给 C 中的函数 [英] Passing an array of strings as parameter to a function in C

查看:52
本文介绍了将字符串数组作为参数传递给 C 中的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要一个简单的函数,它接收一个字符串并在一些解析后返回一个字符串数组.所以,这是我的函数签名:

int parse(const char *foo, char **sep_foo, int *sep_foo_qty) {国际我;字符 * 令牌;...strcpy(sep_foo[i], 令牌);/* 这里是 sf */...}

然后我这样称呼它:

char sep_foo[MAX_QTY][MAX_STRING_LENGTH];字符 foo[MAX_STRING_LENGTH];int sep_foo_qty,错误;...错误 = 解析(foo,sep_foo,&sep_foo_qyt);...

这样我在编译过程中就会收到警告:

警告:从不兼容的指针类型传递解析"的参数 2

然后在用/* sf here 标记的行中执行期间出现分段错误 */

我的 C 代码有什么问题?

提前致谢

解决方案

警告完全正确.您的函数需要一个指针数组.你给它一个数组数组.

预期:

<前>sep_foo:+------+ +-----+|char**|--> 0: |char*|-->"string1"+------+ +-----+1: |char*|-->"string2"+-----+*sep_foo_qty-1: |... |+-----+

您提供的内容:

<前>sep_foo:+--------------------------------+0: |字符[MAX_STRING_LENGTH] |+--------------------------------+1: |字符[MAX_STRING_LENGTH] |+--------------------------------+MAX_QTY-1: |... |+--------------------------------+

具有X 类型元素的数组可以衰减"为指向XX* 的指针.但是 X 的值在那个转换中是不允许改变的.只允许一个衰减操作.你需要它发生两次.在您的情况下, XMAX_STRING_LENGTH 字符数组.该函数希望 X 成为指向字符的指针.由于这些不一样,编译器会警告您.我有点惊讶这只是一个警告,因为编译器允许发生的事情不会带来任何好处.

在您的函数中,您可以编写以下代码:

char* y = NULL;*sep_foo = y;

这是合法的代码,因为 sep_foo 是一个 char**,所以 *sep_foo 是一个 char*y 也是如此;你可以分配它们.但是根据您的尝试,*sep_foo 不会真的成为char*;它将指向一个字符数组.实际上,您的代码将尝试执行此操作:

字符目标[MAX_STRING_LENGTH];字符* y = NULL;目的地 = y;

您不能将指针分配到数组中,因此编译器警告该调用无效.

有两种方法可以解决这个问题:

  • 改变你在调用方声明和分配 sep_foo 的方式,使其与函数期望接收的内容相匹配:

    char** sep_foo = calloc(MAX_QTY, sizeof(char*));for (int i = 0; i 

    或者,等效地

    char* sep_foo[MAX_QTY];for (int i = 0; i 

  • 改变函数的原型以接受你真正给它的东西:

    int parse(const char *foo, char sep_foo[MAX_QTY][MAX_STRING_LENGTH], int *sep_foo_qty);

I want a simple function that receives a string and returns an array of strings after some parsing. So, this is my function signature:

int parse(const char *foo, char **sep_foo, int *sep_foo_qty) {
    int i;
    char *token;
    ...
    strcpy(sep_foo[i], token); /* sf here */
    ...
}

Then I call it like this:

char sep_foo[MAX_QTY][MAX_STRING_LENGTH];
char foo[MAX_STRING_LENGTH];
int sep_foo_qty, error;

...

error = parse(foo, sep_foo, &sep_foo_qyt);

...

This way I get a warning during compilation:

warning: passing argument 2 of 'parse' from incompatible pointer type

And then a segmentation fault during execution in the line marked with /* sf here */

What is wrong in my C code?

Thanks in advance

解决方案

The warning is exactly right. Your function wants an array of pointers. You're giving it an array of arrays.

Expected:

 sep_foo:
 +------+       +-----+
 |char**|--> 0: |char*|-->"string1"
 +------+       +-----+
             1: |char*|-->"string2"
                +-----+
*sep_foo_qty-1: |...  |
                +-----+

What you provided:

           sep_foo:
           +--------------------------------+
        0: | char[MAX_STRING_LENGTH]        |
           +--------------------------------+
        1: | char[MAX_STRING_LENGTH]        |
           +--------------------------------+
MAX_QTY-1: | ...                            |
           +--------------------------------+

An array with elements of type X can "decay" into a pointer-to-X, or X*. But the value of X isn't allowed to change in that conversion. Only one decay operation is allowed. You'd need it to happen twice. In your case, X is array-of-MAX_STRING_LENGTH-chars. The function wants X to be pointer-to-char. Since those aren't the same, the compiler warns you. I'm a bit surprised it was just a warning since nothing good can come from what the compiler allowed to happen.

In your function, you could write this code:

char* y = NULL;
*sep_foo = y;

That's legal code since sep_foo is a char**, so *sep_foo is a char*, and so is y; you can assign them. But with what you tried to do, *sep_foo wouldn't really be a char*; it would be pointing to an array of char. Your code, in effect, would be attempting to do this:

char destination[MAX_STRING_LENGTH];
char* y = NULL;
destination = y;

You can't assign a pointer into an array, and so the compiler warns that the call is no good.

There are two ways to solve this:

  • Change the way you declare and allocate sep_foo on the calling side so it matches what the function expects to receive:

    char** sep_foo = calloc(MAX_QTY, sizeof(char*));
    for (int i = 0; i < MAX_QTY; ++i)
      sep_foo[i] = malloc(MAX_STRING_LENGTH);
    

    or, equivalently

    char* sep_foo[MAX_QTY];
    for (int i = 0; i < MAX_QTY; ++i)
      sep_foo[i] = malloc(MAX_STRING_LENGTH);
    

  • Change the prototype of the function to accept what you're really giving it:

    int parse(const char *foo, char sep_foo[MAX_QTY][MAX_STRING_LENGTH], int *sep_foo_qty);
    

这篇关于将字符串数组作为参数传递给 C 中的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆