Mst137
Mst137

Reputation: 135

Passing part of a structure in C

I have a structure declared like so:

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

However when I try to call the function OpenDatabase(char* filepath, ...) I get an error. I call it like this:

OpenDatabase(Filepath.InstrumentDB, db);

However when I create a new char array of the same size but in a separate variable not attributed to the structure it works? Why is this? Surely they are of the same type?

EDIT: Filepath.InstrumentDB is declared like this :

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

And this is the error i get: error: incompatible types when assigning to type ‘char[128]’ from type ‘char *’

Upvotes: 1

Views: 80

Answers (2)

haylem
haylem

Reputation: 22673

Invalid Initialization

Your code is invalid:

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

If I try this with a minimal example, I get this error with 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";
  ~~~~~~~~~~~~~~~~~~~~ ^

You are attempting to override a static initializer. The memory for your InstrumentDB field is already allocated at when you create your structure. Instead, simply reuse it by copying the data you need.

Working Minimal Examples

With a Dynamic Copy

This works as intended:

#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);
}

A Quick Note on String Copy Actions:

C-strings are null-terminated by convention. Note that in the above example I used the strcpy() function for the sake of simplicity. However, should your input string come from a non-static source (ie I/O of any kind like user-input, file input, ...), not be null-termined, or your software be constructed in a way that may allow to modify the intended purpose, you'd want to guard against buffer overflow/overrun errors by using explicit copy actions (for instance strncpy, or strlcpy/lstrcpy, depending on target environments).

Thanks to users StoryTeller and iwin for pointing this out.

With a Static Initialization

Replacing the initialization line in the sample above with this would also work:

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

Upvotes: 3

Peter
Peter

Reputation: 36617

An array cannot be assigned to. You'll get the same type of error if you do

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

Instead, you need to use string functions

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

More generally, you need to read up on strings in C. The reason <string.h> exists is because numerous operations involving strings (which are represented as an array of char) do not work in the way you are expecting.

Upvotes: 1

Related Questions