C structure rest

  • Thread starter devaraj.takhellambam
  • Start date
D

devaraj.takhellambam

Hi,

I am hoping to get some help from you. Basically, I have a structure in
my c program and the structure is used to store the values of a table
row by row and does some processing. At the end of one row processing,
I would like to clear the contents of each members of the structure
which has different data typebefore processing the next row. Can this
be done? Please let me know.

struct table_1
{
char col1[4] ;
char col2[7] ;
char col3[7] ;
char col4[4] ;
long dt_dt ;
char temp1[3] ;
char col5_i[2] ;
char col6_i[2] ;
char col7[2] ;
char col5[2] ;
} ;

Thanks a lot..

Dev-
 
K

Kai-Uwe Bux

Hi,

I am hoping to get some help from you. Basically, I have a structure in
my c program and the structure is used to store the values of a table
row by row and does some processing. At the end of one row processing,
I would like to clear the contents of each members of the structure
which has different data typebefore processing the next row. Can this
be done? Please let me know.

struct table_1
{
char col1[4] ;
char col2[7] ;
char col3[7] ;
char col4[4] ;
long dt_dt ;
char temp1[3] ;
char col5_i[2] ;
char col6_i[2] ;
char col7[2] ;
char col5[2] ;
} ;

Sure, you can use:

#include <string>
#include <cstddef>

template < typename CharT, std::size_t N >
void clear ( CharT (&arg) [N] ) {
std::char_traits< CharT >::assign( arg, N, CharT() );
}

and then do

void clear ( table_1 & arg ) {
clear( arg.col1 );
// ...
arg.dt_dt = 0;
// ...
}


Best

Kai-Uwe Bux
 
K

Kai-Uwe Bux

Kai-Uwe Bux said:
Hi,

I am hoping to get some help from you. Basically, I have a structure in
my c program and the structure is used to store the values of a table
row by row and does some processing. At the end of one row processing,
I would like to clear the contents of each members of the structure
which has different data typebefore processing the next row. Can this
be done? Please let me know.

struct table_1
{
char col1[4] ;
char col2[7] ;
char col3[7] ;
char col4[4] ;
long dt_dt ;
char temp1[3] ;
char col5_i[2] ;
char col6_i[2] ;
char col7[2] ;
char col5[2] ;
} ;
[snip some incredibly convoluted stuff]

Well, here is another try:

t = table_1();

as in:


struct table_1 {
char col1[4] ;
char col2[7] ;
char col3[7] ;
char col4[4] ;
long dt_dt ;
char temp1[3] ;
char col5_i[2] ;
char col6_i[2] ;
char col7[2] ;
char col5[2] ;
};


#include<iostream>

int main ( void ) {
table_1 t;
t.dt_dt = 1;
t.col1[0] = 'a';
std::cout << t.col1[0] << " " << t.dt_dt << '\n';
t = table_1();
std::cout << t.col1[0] << " " << t.dt_dt << '\n';
}


Best

Kai-Uwe Bux
 
P

Phlip

Kai-Uwe Bux said:
devaraj.takhellambam wrote:
template < typename CharT, std::size_t N >

You are kind'a cruel, Kai-Uwe. Don't tempt devaraj with high-level C++
things when low-level C is the issue.

devaraj, you should post this question to , where they will
probably recommend how to use memset() safely. However, you also asked how
to "clear the contents of each members of the structure which has different
data typebefore processing the next row." That's between you and your
database, so there might not be a generic C solution.
 
K

Kai-Uwe Bux

Phlip said:
You are kind'a cruel, Kai-Uwe. Don't tempt devaraj with high-level C++
things when low-level C is the issue.

I wasn't trying to be mean -- I wasn't thinking properly (see my
self-reply). However, posting to this news group, any poster should be
prepared to receive C++ suggestions.

devaraj, you should post this question to , where they
will probably recommend how to use memset() safely.

That is exactly how I started: using memset. Then, of course, you look up
the signature and you find this void* and the length parameter and you
think: that should be needed in C++. This is what led me to look up
char_traits, because I had this recollection that there one finds the C++
versions of memset() and its friends. The template then is actually needed
to avoid keeping track of the lengths manually.

However, you also
asked how to "clear the contents of each members of the structure which
has different data typebefore processing the next row." That's between you
and your database, so there might not be a generic C solution.

Oops, I missed out on that issue entirely: only selected fields are to be
cleared. Well, then what about the generic clear() template:

template < typename T >
T & clear ( T & t ) {
t = T();
return ( t );
}

Of course, now one still has to write some non-generic code to figure out
which fields to clear.


Best

Kai-Uwe Bux
 
F

Frederick Gotham

Kai-Uwe Bux posted:
t = table_1();

Only thing though is that that doesn't work for arrays. I think the only
good portable way of "clearing" any kind of object is:

#include<new>

template<class T>
void Clear(T &obj)
{
obj.~T();

::new(&obj) T();
}

/* Now some types to test it out on */

#include <string>

struct MyPOD { int i; char b; void *p; };

int main()
{
std::string obj1;
MyPOD obj2;
int obj3;
double obj4[5];
MyPOD obj5[7];
std::string obj6[2];

Clear(obj1); Clear(obj2); Clear(obj3); Clear(obj4);
Clear(obj5); Clear(obj6);
}

At first, I was tempted to do:

memcpy(&obj,
&reinterpret_cast<T const &>(T()),
sizeof(T));

, but then I realised it would be just as handy to destruct and re-
construct the original object in-place (also, we have the problem of not
being allowed to move around objects willy-nilly, as their internal
workings may depend on the object's address).
 
K

Kai-Uwe Bux

Frederick said:
Kai-Uwe Bux posted:


Only thing though is that that doesn't work for arrays. I think the only
good portable way of "clearing" any kind of object is:

#include<new>

template<class T>
void Clear(T &obj)
{
obj.~T();

::new(&obj) T();
}
[snip]

Right, I thought about that later. The version, I added to my library is
this:

template < typename T >
T & reinitialize ( T & t ) {
/*
| The natural idea
|
| t = T();
|
| requires assignability and default constructability.
| The following looks scary, but is a little less demanding:
| it requires just default constructability and destructability.
*/
// destroy:
address_of( t )->~T();
// reconstruct:
new ( ( void*) address_of( t ) ) T ();
return ( t );
}

where address_of used to deal with classes that think they need to tamper
with the built-in address operator. It is effectively stolen from Boost:

template < typename T >
T * address_of (T & t) {
return (
reinterpret_cast<T*>(
& const_cast<char&>(
reinterpret_cast<const volatile char &>( t ) ) ) );
}


Best

Kai-Uwe Bux
 
F

Frederick Gotham

Kai-Uwe Bux posted:
template < typename T >
T & reinitialize ( T & t ) {
/*
| The natural idea
|
| t = T();
|
| requires assignability and default constructability.
| The following looks scary, but is a little less demanding:
| it requires just default constructability and destructability.
*/
// destroy:
address_of( t )->~T();


Good one, I hadn't thought of that.

// reconstruct:
new ( ( void*) address_of( t ) ) T ();


Is the void* cast necessary? Could we not simply have:

::new(address_of(t)) T();
 
K

Kai-Uwe Bux

Frederick said:
Kai-Uwe Bux posted:



Good one, I hadn't thought of that.




Is the void* cast necessary? Could we not simply have:

::new(address_of(t)) T();

Good question. What led me to stick in the (void*) cast is the following
remark from the standard about the semantics of

std::allocator<T>::construct()

The standard [20.4.1.1/12] says:

void construct(pointer p, const_reference val);
Returns: new((void *)p) T(val)

I just copied that, hoping the authors of the standard had thought carefully
about how the standard allocator should construct an object. I think, the
(void*) makes sure that overloaded versions of new do not match. It is
quite possible that using ::new does that too.


Best

Kai-Uwe Bux
 
D

devaraj.takhellambam

As my program is in C and not c++, is there any easier meathod to do
that like using memset or something. Please let me know.


Kai-Uwe Bux said:
Frederick said:
Kai-Uwe Bux posted:



Good one, I hadn't thought of that.




Is the void* cast necessary? Could we not simply have:

::new(address_of(t)) T();

Good question. What led me to stick in the (void*) cast is the following
remark from the standard about the semantics of

std::allocator<T>::construct()

The standard [20.4.1.1/12] says:

void construct(pointer p, const_reference val);
Returns: new((void *)p) T(val)

I just copied that, hoping the authors of the standard had thought carefully
about how the standard allocator should construct an object. I think, the
(void*) makes sure that overloaded versions of new do not match. It is
quite possible that using ::new does that too.


Best

Kai-Uwe Bux
 
K

Kai-Uwe Bux

As my program is in C and not c++, is there any easier meathod to do
that like using memset or something. Please let me know.

(a) please don't top post in this group. It is frowned upon and considered
poor form around these parts.

(b) please don't post in this group if you have a C question. The folks at
comp.lang.c will be happy to take your question. Hint: as far as I know,
(a) applies in that forum, as well.

(c) Other than that: memset() is worth a shot. Beware, however, that using
memset requires you to manually pass the length of the string that you want
to clear: that makes it actually less easy than using the C++ template
function. Thus, you probably want to write a few helper functions like so:

clear_field_1 ( table_1 * t_ptr ) {
memset( &(t_ptr->col1), 0, 4 );
}

clear_field_2 ( table_1 * t_ptr ) {
...

(1) warning: untested code. might be totally bogus
(2) in C++, you would use a reference instead of a pointer.


Best

Kai-Uwe Bux
 
F

Frederick Gotham

Devaraj posted:
As my program is in C and not c++, is there any easier meathod to do
that like using memset or something. Please let me know.


You won't get much more help here. I left you a reply over on comp.lang.c.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,071
Latest member
MetabolicSolutionsKeto

Latest Threads

Top