简体   繁体   English

在C语言中的函数内部更改字符串数组

[英]Changing a Array of Strings inside a function in C

What I'm trying to do is pretty straight forward in other languages. 我正在尝试使用其他语言直接进行操作。 But I'm struggling with this in a C project and didn't find a right way to do it in my researches. 但是我在C项目中为此而苦苦挣扎,并且在我的研究中没有找到正确的方法。

What I need to do is: 我需要做的是:

  1. Declare an global empty array of strings 声明一个全局的空字符串数组
  2. Inside a function I want to populate this global array with X new strings 在函数内部,我想用X个新字符串填充此全局数组
  3. In another function, I want loop through all new elements of this array printing them out. 在另一个函数中,我想遍历此数组的所有新元素,将它们打印出来。

The code I have now is listed below. 我现在拥有的代码在下面列出。

#include <stdio.h>

const char *menu[] = {};

void populateMenu(){

    // populate this menu with some itens
    *menu = {
        "New item A",
        "New item B",
        NULL
    };
}

int main(int argc, const char * argv[])
{

    // 1. print inicial menu

    int menuAlen = sizeof(menu)/sizeof(*menu);
    int i;
    for(i = 0; i < menuAlen; i++){
        printf("%s\n", menu[i]);
    }

    // 2. populate the menu
    populateMenu();

    // 3. print it again with new values
    int menuBlen = sizeof(menu)/sizeof(*menu);
    for(i = 0; i < menuBlen; i++){
        printf("%s\n", menu[i]);
    }

    return 0;
}

I'm currently getting this error on build time. 我目前在构建时遇到此错误。

main.c:16:16: Expected expression main.c:16:16:预期表达

Line 16 is the first line inside populateMenu function. 第16行是populateMenu函数内部的第一行。

Can someone help me out with this? 有人可以帮我这个忙吗? Thanks in advance. 提前致谢。

Best. 最好。 George. 乔治。

You should declare menu as a pointer to [some array of] pointer strings: 您应该将menu声明为指向[某些]指针字符串数组的指针:

char**menu;

You need to know the number of menu entries. 您需要知道菜单条目的数量。 So declare also 所以也要声明

size_t nb_menu;

and have some way to compute it at runtime . 并有一些在运行时计算它的方法。 (I leave that up to you, but you cannot use sizeof which is a compile-time thing). (我让您自己决定,但是您不能使用sizeof这是编译时的东西)。

You then allocate in the heap, using calloc(3) , that array: 然后,使用calloc(3)在堆中分配该数组:

menu = calloc (nb_menu+1, sizeof(char*));
if (!menu) { perror("calloc menu"); exit (EXIT_FAILURE); };

I'm doing nb_menu+1 because you probably want to NULL terminate your menu . 我正在执行nb_menu+1因为您可能想将NULL终止menu

Now you could fill it, eg 现在您可以填充它,例如

menu[0] = "Some string";

or better yet, use strdup(3) . 更妙的是,使用strdup(3)

You should have a convention (and document it) about when and which pointers are into the heap -ie; 您应该有一个约定(并记录下来),有关何时以及哪些指针进入堆的信息。 malloc -ed or calloc -ed and who should free them. malloc -ed或calloc -ed,谁应该free它们。

You should later free(3) your pointers to avoid memory leaks . 您稍后应释放指针(3)以避免内存泄漏 You can only free a pointer obtained by malloc or calloc or strdup (which calls malloc ) etc... 您只能free通过malloccallocstrdup (调用malloc )等获得的指针。

On Linux, you should learn how to use valgrind . 在Linux上,您应该学习如何使用valgrind Perhaps using Boehm Garbage Collector could help you. 也许使用Boehm垃圾收集器可以为您提供帮助。 Certainly, understand what garbage collectors are and learn a lot more about C memory management . 当然,了解什么是垃圾回收器并了解有关C内存管理的更多信息。

Actually, you could use flexible array members and have your menu be a pointer to 实际上,您可以使用灵活的数组成员,并使menu成为指向

struct menu_st {
  unsigned nb_entries;
  char* entry_array[]; // nb_entries elements in the array
};

Read about the C memory model . 阅读有关C内存模型的信息

Don't forget to compile with all warnings and debug info (eg gcc -Wall -g ) and learn how to use the debugger (eg gdb ). 不要忘记编译所有警告和调试信息(例如gcc -Wall -g ),并学习如何使用调试器(例如gdb )。 Be very scared of undefined behavior . 非常害怕不确定的行为

#include <stdio.h>

const char **menu = NULL;

void populateMenu(){
    static const char *items[] = {
        "New item A",
        "New item B",
        NULL
    };
    menu = items;
}

int menuLen(const char **menu){
    int len = 0;
    if(!menu) return 0;
    while(*menu++)
        ++len;
    return len;
}

int main(int argc, const char * argv[]){
    // 1. print inicial menu

    int menuAlen = menuLen(menu);
    int i;
    for(i = 0; i < menuAlen; i++){
        printf("%s\n", menu[i]);
    }

    // 2. populate the menu
    populateMenu();

    // 3. print it again with new values
    int menuBlen = menuLen(menu);
    for(i = 0; i < menuBlen; i++){
        printf("%s\n", menu[i]);
    }

    return 0;
}

I hate global variables. 我讨厌全局变量。 I suggest you create the array inside main() and pass it throughout your code as needed. 我建议您在main()创建数组,并根据需要在整个代码中传递它。

// #includes ...
// prototypes
int main(void) {
    char menu[1000][80]; // space for 1000 strings each up to 79 characters long
    size_t nmenu;        // number of string in menu

    nmenu = populate(menu); // change contents of array, set nmenu
    menuprint(menu, nmenu); // print

    return 0;
}

The rest of the program (the functions populate() and menuprint() ) is up to you. 程序的其余部分(函数populate()menuprint() )由您决定。

Note: the 1000 and 80 are large(ish) estimates. 注意: 100080是较大的估计。 A better way to do it would be with dynamic memory allocation. 更好的方法是使用动态内存分配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM