On 17/10/2012 8:08 AM, Noob wrote:
> gus gassmann wrote:
>
> First of all, it is not clear what "C/C++" means.
> There is C, and there is C++.
>
>> I have a static struct, defined in a C header file as something like
>>
>> typedef struct
>> SomeStruct {
>> char *name;
>> int kind;
>> int value;
>> }
>
> Nit: you should copy/paste the EXACT code. The above does not make sense.
> (warning: useless storage class specifier in empty declaration)
>
> I think you meant:
>
> typedef struct { char *name; int kind; int value; } SomeStruct;
>
> which defines an anonymous struct, and defines "SomeStruct"
> as a synonym. (AFAIU, this is done "automatically" in C++)
>
>> and I need to supply (in C++) values to an array of this type. I
>> understand that I can set *static* values by
>>
>> static SomeStruct
>> myStruct[] = {
>> {"name1", 1, 17},
>> {"name2", 7, 25},
>> {"name3", 3, 6},
>> {"name4", 0,117}
>> };
>>
>> However, I need to set dynamic values along these lines (I know that the
>> code does not work):
>>
>> static SomeStruct
>> myStruct[] = {
>> {name[0], kind[0], val[0]},
>> {name[1], kind[1], val[1]},
>> ...
>> {name[n], kind[n], val[n]},
>> };
>>
>> where both the values and the number of values are only known at
>> runtime. I cannot change the definition in the header file; I am not
>> even sure that what I want to do is possible. Any ideas?
>
> If the size of the array is not known at compile-time, then you
> need dynamic memory allocation.
>
> In C, you could write:
>
> #include <stdlib.h>
> typedef struct { char *name; int kind; int value; } SomeStruct;
> static SomeStruct *array;
> void array_init(int n, char **name, int *kind, int *value)
> {
> int i;
> array = malloc(n * sizeof *array);
> for (i = 0; i < n; ++i)
> {
> SomeStruct temp = { name[i], kind[i], value[i] };
> array[i] = temp;
> }
> }
>
> In C++, they use new and new[] instead of malloc.
Thanks to all who responded. As Jorgen Grahn surmised, I am not allowed
to change the C header file. I like Noob's solution, because it seems
simple and uses an idiom that I am familiar with. I therefore tried to
incorporate it into my file, making some adjustments I thought
necessary, and ran into trouble I cannot fathom. I would be grateful for
further assistance.
First, the C header file test.h. (I tried to simplify as much as
possible, while being faithful to the functionality I will need.)
#ifndef test_processed
#define test_processed
typedef struct
MyStruct {
char *name;
int kind;
int nextra;
} MyStruct;
#endif
Then the C++ code.
#include "test.h"
#include <sstream>
std::string get_str();
int get_dim();
int get_int();
int main(){
int ndim;
MyStruct *myStruct = 0;
ndim = get_dim();
myStruct = new MyStruct[ndim];
for (int i=0; i < ndim; i++)
{
myStruct[i] = {{(const)(get_str().c_str()), 0,
get_int()}};
}
return 0;
}
std::string get_str()
{
return "test";
}
int get_dim()
{
return 7;
}
int get_int()
{
return 2;
}
This gives the following error messages:
test.cpp: In function ‘int main()’:
test.cpp:18:34: error: ISO C++ forbids declaration of ‘type name’ with
no type
test.cpp:18:58: error: cast from ‘const char*’ to ‘const int’ loses
precision
test.cpp:18:74: warning: extended initializer lists only available with
-std=c++0x or -std=gnu++0x
test.cpp:18:74: warning: extended initializer lists only available with
-std=c++0x or -std=gnu++0x
test.cpp:18:74: error: no match for ‘operator=’ in ‘*(myStruct + ((long
unsigned int)(((long unsigned int)i) * 16ul))) = {{((const int)((long
int)get_str()().std::basic_string<_CharT, _Traits, _Alloc>::c_str [with
_CharT = char, _Traits = std::char_traits<char>, _Alloc =
std::allocator<char>]())), 0, get_int()}}’
test.h:2:10: note: candidate is: MyStruct& MyStruct:

perator=(const
MyStruct&)
The first two have me confused. (Not that the others are any clearer,
but there I do not even understand what the error message means.) Isn't
'name' defined in the header file? And why does the compiler think I am
trying to cast to 'const int'?
BTW, I first tried
void main()
but the compiler complained that main() must return an integer, so I
changed it. I thought a void main was the proper thing.
Can anyone help me? (As you see, I no speaka da C++ so good, so please
be gentle.)
gus