PDA

Visualizza la versione completa : [C++] costruttore su string e char


gianvituzzi
25-01-2010, 23:10
Salve,

il seguente è una struttura con costruttore:



struct Buffer
{
string payload;
int user;
Buffer() : payload(), user() { }
Buffer( const string& payload, int user ) : payload(payload), user(user) { }
};


che uso con: Buffer buff("hello", 2010);

c'è un modo per creare un costruttore simile per la seguente struttura?



struct Buffer
{
char data[1024];
int user;
(...)
};


grazie

MItaly
25-01-2010, 23:17
struct Buffer
{
char data[1024];
int user;
Buffer(const char * Data, int User) : user(User)
{
if(strlen(Data)>=sizeof(data))
throw std::runtime_error("Stringa troppo lunga.");
strcpy(data,Data);
}
};

Comunque la classe string ti evita un sacco di seccature, io la userei se fossi in te.

gianvituzzi
25-01-2010, 23:37
ok, ti ringrazio! Solo che per ammutolire il compilatore devo fare:



struct cBuffer
{
char data[1024];
int bytesRecorded;
bool flag;
cBuffer(const char * data_, const int bytesRecorded_, const bool flag_) :
bytesRecorded(bytesRecorded_), flag(flag_)
{
strcpy_s(data, strlen(data_), data_);
}
};


cmq per adesso non posso usare std::string perchè devo utilizzare flussi binari

gianvituzzi
25-01-2010, 23:52
quindi ho tutto il codice del buffer circolare così:



#include <windows.h>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <cstring>
#include <boost/circular_buffer.hpp>
using namespace std;
using namespace boost;

void getDateTime(char * szTime);
const int numbuff = 3;
const int buflen = 30;

struct cBuffer
{
char data[1024];
int bytesRecorded;
bool flag;
cBuffer(char * data_, int bytesRecorded_, bool flag_) :
bytesRecorded(bytesRecorded_), flag(flag_)
{
memcpy(static_cast<void *>(data), static_cast<void *>(data_), bytesRecorded);
}
};


int main()
{
circular_buffer<cBuffer> cb(numbuff);

// Insert elements
printf("Push elements:\n");
for(int i = 0; i < 5; i++)
{
char szTime[30]; getDateTime(szTime);

cb.push_back(cBuffer(szTime, 30, true));

printf("%s\n", szTime);

Sleep(1000);
}

// Show elements:
printf("Show elements:\n");
for(int i = 0; i<(int)cb.size(); i++)
{
printf("%s\n", cb[i].data);
}

system("pause");
return EXIT_SUCCESS;
}

void getDateTime(char * szTime)
{
time_t rawtime = time(NULL);
struct tm timeinfo;
gmtime_s(&timeinfo, &rawtime);
strftime(szTime, 30, "%a, %d %b %Y %X GMT", &timeinfo);
}


penso che ora davvero non incorrerò in memory leaks...

grazie

MItaly
25-01-2010, 23:55
Allora le varie strcpy non vanno bene, dato che nei flussi binari ci possono essere dei NUL.
Devi usare la memcpy e tenere in un campo separato (un size_t, ad esempio) il numero di byte effettivamente contenuti per il buffer.

gianvituzzi
25-01-2010, 23:57
Originariamente inviato da MItaly
Allora le varie strcpy non vanno bene, dato che nei flussi binari ci possono essere dei NUL.
Devi usare la memcpy e tenere in un campo separato (un size_t, ad esempio) il numero di byte effettivamente contenuti per il buffer.

vedi sopra

gianvituzzi
26-01-2010, 00:05
solo una cosa, nel seguente codice:



struct cBuffer
{
char data[1024];
int bytesRecorded;
bool flag;
cBuffer(char * data_, int bytesRecorded_, bool flag_) :
bytesRecorded(bytesRecorded_), flag(flag_)
{
memcpy(static_cast<void *>(data), static_cast<void *>(data_), bytesRecorded);
}
};


non posso fare più const char * data perchè mi da un errore di casting...come posso ovviare?

grazie

MacApp
26-01-2010, 01:14
Originariamente inviato da gianvituzzi
non posso fare più const char * data perchè mi da un errore di casting...come posso ovviare?


in C++ meglio usare gli algoritmi std piuttosto che le varie memcpy o memmove


/*

$ g++ --version; g++ -Wall -ansi -pedantic -Wextra -Wconversion main.cpp; ./a.out
i686-apple-darwin8-g++-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5367)
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

aBuffer.data: Hello World!;

*/

#include <algorithm>
#include <iostream>

namespace ig{
struct cBuffer
{
char data[1024];
int bytesRecorded;
bool flag;
cBuffer(const char * data_, int bytesRecorded_, bool flag_) :
bytesRecorded(bytesRecorded_), flag(flag_)
{
// memcpy(static_cast<void *>(data), reinterpret_cast<void *>(data_), bytesRecorded);
std::copy (data_, data_ + bytesRecorded_, data);
}
};
}

int main (void){
const char * aSampleStr = "Hello World!";
ig::cBuffer aBuffer (aSampleStr, std::strlen (aSampleStr) + 1, false);
std::cout << "aBuffer.data: "<< aBuffer.data << ";"<< std::endl;
return 0;
}

gianvituzzi
26-01-2010, 04:11
solo una domanda...se uso std::copy in questo modo:



copy(data_, data_ + (bytesRecorded_ * sizeof(char)), data);


ovvero copio 30 caratteri in char data[1024] tutto il resto sarà nullpadded?? la stessa domanda vale per memcpy...

MItaly
26-01-2010, 10:15
No, ma effettivamente che ti importa? Basta che copi sempre esattamente tanti byte quanti ti sono stati forniti all'inizio.
Ah, un consiglio: dal momento che si tratta di dati binari, usa un unsigned char o fai un typedef per creare il tipo byte basato su unsigned char, così è subito evidente che non si tratta di una stringa.

Loading