【问题标题】:Passing part of a structure in C在 C 中传递结构的一部分
【发布时间】:2016-12-16 14:05:44
【问题描述】:

我有一个这样声明的结构:

typedef struct {
    char InstrumentDB[128];
    char GeneralSettingsDB[128];
    char LiveDB[128];
    char SystemsDB[128];
} Address;

但是,当我尝试调用函数 OpenDatabase(char* filepath, ...) 时,我得到一个错误。我这样称呼它:

OpenDatabase(Filepath.InstrumentDB, db);

但是,当我创建一个大小相同但在不归因于结构的单独变量中的新 char 数组时,它会起作用吗?为什么是这样?确定它们是同一类型的吗?

编辑:Filepath.InstrumentDB 声明如下:

Address Filepath;
Filepath.InstrumentDB = "/root/BBBTest/Instruments.db";

这是我得到的错误:error: incompatible types when assigning to type ‘char[128]’ from type ‘char *’

【问题讨论】:

  • “我收到一个错误” - 什么错误?
  • 那么Filepath是如何定义和初始化的?
  • 请添加一个显示错误的最小示例(并在您的问题中包含错误)。
  • 可以很好地编译一个超级最小的例子:gist.github.com/anonymous/f463003547050e14aef069974e57ad95。你有什么问题。
  • 要复制一个字符串,你不能只分配它,而必须使用 strcpy(Filepath.InstrumentDB, "...")

标签: c arrays function char structure


【解决方案1】:

初始化无效

您的代码无效:

Address Filepath;
Filepath.InstrumentDB = "/root/BBBTest/Instruments.db";

如果我用一个最小的例子来尝试这个,我会在 LLVM 7.3 中得到这个错误:

~/tmp> gcc -Wall -pedantic -ansi test.c
test.c:19:24: error: array type 'char [128]' is not assignable
  address.InstrumentDB = "/root/BBBTest/Instruments.db";
  ~~~~~~~~~~~~~~~~~~~~ ^

您正在尝试覆盖静态初始化程序。 InstrumentDB 字段的内存已在您创建结构时分配。相反,只需复制您需要的数据即可重复使用它。

工作最小示例

使用动态副本

这按预期工作:

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


typedef struct {
  char InstrumentDB[128];
} Address;

void OpenDatabase(char* filepath) {
  /* do stuff */
  printf("%s\n", filepath);
}


int main(int ac, char **av) {
  Address address;
  strcpy(address.InstrumentDB, "test");
  OpenDatabase(address.InstrumentDB);
}

关于字符串复制操作的快速说明:

C 字符串按照惯例以空值结尾。请注意,在上面的示例中,为了简单起见,我使用了 strcpy() 函数。但是,如果您的输入字符串来自非静态源(即任何类型的 I/O,如用户输入、文件输入等),不是以 null 结尾的,或者您的软件的构建方式可能允许修改预期目的,您需要通过使用显式复制操作(例如 strncpystrlcpy/lstrcpy,具体取决于目标环境)来防范 buffer overflow/overrun 错误。

感谢用户 StoryTeller 和 iwin 指出这一点。

使用静态初始化

用这个替换上面示例中的初始化行也可以:

int main(int ac, char **av) {
  Address address = {
    "test2"
  };
  OpenDatabase(address.InstrumentDB);
}

【讨论】:

  • 或许应该使用strncpy而不是strcpy
  • @haylem,因为结构定义可能隐藏在某些标头中,而有人无意中更改了静态初始化程序并忘记计算字符数。
  • @StoryTeller:关于标准库是真的,我的错,它也不是 POSIX 的一部分。对不起。就像我说的,多年来没有编写 C 代码,所以我只启动了一个 emacs 和编译器来快速旋转。我更害怕 iwin 指出我的知识差距或者我的理解已经过时了。感谢您纠正我。
  • @StoryTeller:修改了答案以涵盖这一点,尽管将代码示例保留为简单形式。
  • @iwin:已修改。谢谢。
【解决方案2】:

无法分配数组。如果你这样做,你会得到相同类型的错误

int main()
{
     char buf[10];
     buf = "Hello";
}

相反,您需要使用字符串函数

#include <string.h>
int main()
{
     char buf[10];
     strcpy(buf, "Hello");
}

更一般地说,您需要阅读 C 中的字符串。&lt;string.h&gt; 存在的原因是因为涉及字符串的许多操作(表示为 char 的数组)不能按您期望的方式工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-26
    • 2015-03-23
    • 1970-01-01
    相关资源
    最近更新 更多