-
Converting from C to C++
Hey guys. I have the below code in C but I need to convert it to C++, any ideas about where to start and what would need to change majorly would be appreciated.
Code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#define DELIM ":"
struct pktnode
{
int pkt_id;
char *message;
struct pktnode *next;
};
struct messagenode
{
int msg_id;
int prefix_len;
char id_prefix[3];
struct pktnode *pkthead;
struct messagenode *next;
};
void initiate(char *filename, FILE **fp, char **packet);
void populateInList(char *packet, struct messagenode **msg_node, FILE **fp);
struct messagenode *getMsgNode();
struct pktnode *getPktNode();
struct messagenode *search_msg(int msg_id, struct messagenode **head_msg);
struct pktnode *search_pkt(int pkt_id, struct pktnode **head_pkt);
void getPacketInfo(char *packet, int *msg_id, int *pkt_id, char *message,
int *prefix_len_msg, struct messagenode **head_msg, FILE **fp);
void display(struct messagenode **head_msg);
void cleanUpAll(struct messagenode **head_msg, FILE **fp, char *packet);
void sortMsg(struct messagenode **head_msg);
int getlen(char *arg);
int main(int argc, char **argv)
{
FILE *fp;
char *packet;
struct messagenode *head_msg = NULL;
if(argc != 2)
{
printf("Must supply 1 argument to packet\n");
return 0;
}
initiate(argv[1], &fp, &packet);
while(1)
{
fgets(packet, 2001, fp);
if(packet == NULL || !strcmp(packet, "END\n")|| !strcmp(packet, "END"))
break;
populateInList(packet, &head_msg, &fp);
}
sortMsg(&head_msg);
display(&head_msg);
cleanUpAll(&head_msg, &fp, packet);
return 0;
}
/* Opening packet data file */
void initiate(char *filename, FILE **fp, char **packet)
{
*fp = fopen(filename, "r");
if(*fp == NULL)
{
printf("Unable to open %s\n", filename);
exit(0);
}
*packet = (char *)malloc(2000 * sizeof(char));
}
/* Get message id, packet id and packet message from each
* packet string passed to function as argument.
*/
void populateInList(char *packet, struct messagenode **head_msg, FILE **fp)
{
int msg_id, pkt_id, prefix_len_msg;
char *message;
struct messagenode *tmp_message, *loc, *current_msg, *save_msg;
struct pktnode *tmp_packet, *loc_pkt, *head_pkt;
message = (char *)malloc(1500*sizeof(char));
getPacketInfo(packet, &msg_id, &pkt_id, message,
&prefix_len_msg, head_msg, fp);
if((loc = search_msg(msg_id, head_msg)) != NULL)
{
tmp_packet = getPktNode();
tmp_packet->pkt_id = pkt_id;
tmp_packet->message = message;
head_pkt = loc->pkthead;
if(head_pkt == NULL)
head_pkt = tmp_packet;
else
{
loc_pkt = search_pkt(pkt_id, &head_pkt);
if(loc_pkt == head_pkt && pkt_id < loc_pkt->pkt_id)
{
tmp_packet->next = head_pkt;
head_pkt = tmp_packet;
loc->pkthead = head_pkt;
}
else
{
tmp_packet->next = loc_pkt->next;
loc_pkt->next = tmp_packet;
}
}
}
else
{
tmp_message = getMsgNode();
tmp_message->msg_id = msg_id;
tmp_message->prefix_len = prefix_len_msg;
tmp_message->next = NULL;
tmp_message->pkthead = getPktNode();
tmp_message->pkthead->pkt_id = pkt_id;
tmp_message->pkthead->message = message;
if(*head_msg == NULL)
*head_msg = tmp_message;
else
{
current_msg = *head_msg;
while(current_msg != NULL)
{
save_msg = current_msg;
current_msg = current_msg->next;
}
save_msg->next = tmp_message;
}
}
}
struct messagenode *getMsgNode()
{
struct messagenode *tmp;
tmp = (struct messagenode *)malloc(sizeof(struct messagenode));
tmp->pkthead = NULL;
return tmp;
}
struct pktnode * getPktNode()
{
struct pktnode *tmp;
tmp = (struct pktnode *)malloc(sizeof(struct pktnode));
tmp->next = NULL;
return tmp;
}
/* Function to search a message node in message linked list. */
struct messagenode *search_msg(int msg_id, struct messagenode **head_msg)
{
struct messagenode *current_msg;
current_msg = *head_msg;
if(*head_msg == NULL)
return NULL;
else
{
while((current_msg != NULL) && (current_msg->msg_id != msg_id))
current_msg = current_msg->next;
if(current_msg == NULL)
return NULL;
if(current_msg->msg_id == msg_id)
return current_msg;
else
return NULL;
}
}
/* Function to search a packet node in packet linked list. */
struct pktnode *search_pkt(int pkt_id, struct pktnode **head_pkt)
{
struct pktnode *current_pkt, *save_pkt;
current_pkt = *head_pkt;
save_pkt = current_pkt;
while((current_pkt != NULL) && (pkt_id > current_pkt->pkt_id))
{
save_pkt = current_pkt;
current_pkt = current_pkt->next;
}
return save_pkt;
}
/* Function to get packet info from packet string. */
void getPacketInfo(char *packet, int *msg_id, int *pkt_id, char *message,
int *prefix_len_msg, struct messagenode **head_msg, FILE **fp)
{
char *tokenPtr = NULL;
char array[10][1500];
char bkp_packet[2000];
int counter = 0, i=0;
strcpy(bkp_packet, packet);
tokenPtr = (char *)strtok(packet, DELIM);
if(tokenPtr == NULL)
{
printf("Fatal Error1 !! Invalid Message Format\n");
cleanUpAll(head_msg, fp, packet);
exit(0);
}
strcpy(array[0], tokenPtr);
counter++;
while(1)
{
tokenPtr = (char *)strtok(NULL, DELIM);
if(tokenPtr == NULL)
break;
strcpy(array[counter], tokenPtr);
if(counter>2)
strcat(array[counter-1], ":");
counter++;
}
if(counter < 3)
{
printf("Fatal Error3 !! Invalid Message Format\n");
cleanUpAll(head_msg, fp, packet);
exit(0);
}
*prefix_len_msg = getlen(array[0]);
*msg_id = atoi(array[0]);
*pkt_id = atoi(array[1]);
for(i=2; i<counter; i++)
{
strcat(message, array[i]);
}
}
int getlen(char *arg)
{
int n=0;
char ch;
while(1)
{
ch = arg[n];
if(ch != '0')
break;
n++;
}
return n;
}
/* Move through formulated linked list and display the content.*/
void display(struct messagenode **head_msg)
{
char display_string[2000];
char prefix[3];
struct messagenode *current_msg;
struct pktnode *current_pkt;
int i;
current_msg = *head_msg;
while(current_msg != NULL)
{
for(i=0; i<current_msg->prefix_len; i++)
prefix[i]= '0';
prefix[i]='\0';
sprintf(display_string, "Message %s%d\n", prefix, current_msg->msg_id);
current_pkt = current_msg->pkthead;
while(current_pkt != NULL)
{
strcat(display_string, current_pkt->message);
current_pkt = current_pkt->next;
}
current_msg = current_msg->next;
printf("%s\n", display_string);
}
}
/* Move through linked list and deallocate it. Close file pointer also */
void cleanUpAll(struct messagenode **head_msg, FILE **fp, char *packet)
{
struct messagenode *current_msg, *head_msg_local;
struct pktnode *current_pkt, *head_pkt;
fclose(*fp);
free(packet);
head_msg_local = *head_msg;
while(head_msg_local != NULL)
{
head_pkt = head_msg_local->pkthead;
while(head_pkt != NULL)
{
free(head_pkt->message);
current_pkt = head_pkt->next;
free(head_pkt);
head_pkt = current_pkt;
}
current_msg = head_msg_local->next;
free(head_msg_local);
head_msg_local = current_msg;
}
}
/* Sort the message linked list, i.e. the outer one.*/
void sortMsg(struct messagenode **head_msg)
{
int tmp_id, tmp_len;
struct pktnode *tmp_head;
struct messagenode *current_msg, *save_msg;
if(*head_msg == NULL)
return;
else
{
for(current_msg = *head_msg; (current_msg != NULL);
current_msg = current_msg->next)
{
for(save_msg = current_msg->next;
(save_msg != NULL); save_msg = save_msg->next)
{
if(current_msg->msg_id > save_msg->msg_id)
{
tmp_id = save_msg->msg_id;
tmp_head = save_msg->pkthead;
tmp_len = save_msg->prefix_len;
save_msg->msg_id = current_msg->msg_id;
save_msg->pkthead = current_msg->pkthead;
save_msg->prefix_len = current_msg->prefix_len;
current_msg->msg_id = tmp_id;
current_msg->pkthead = tmp_head;
current_msg->prefix_len = tmp_len;
}
}
}
}
}
-
Rename the file from .c to .cpp and recompile.
If there are any errors, post them and we'll take a look.
For the most part, C++ is C plus some extra stuff.
I'm a firm believer in the saying "If it ain't broke, don't fix it".
-
You could change the mallocs and frees to news and deletes?
-
I tend to side with cp here - why do you "need" to convert it? If it's working, at most I might put it behind a facade or wrap it.
If you just want to learn, on the other hand, a first step would be to turn the structs into classes, and make functions that operate on them into member functions of those classes.
So, instead of...
Code:
struct foo {};
void doSomething(foo *) {}
Do this...
Code:
class foo {
public:
void doSomething() {}
};
-
Why do this?
Most compilers allow you to compile C and C++ files in the same project (program), at the same time.
-
As discussed, it depends on how far you want to take it. The difficulty ranges from "renaming the file" (and fixing any compiler errors that crop up) to "making the application entirely object oriented".
One thing that comes to mind is to use the STL containers (e.g. list) instead of using your home-made linked list system.
I don't think there is much point in ONLY replacing malloc with new and free with delete - malloc and free are still valid C++ code as long as there is no need to construct an object from the pointer.
In an ultimate made object oriented, you'd have a packet object and a messagenode object which you can manipulate through member functions. That would be essentially a complete rewrite of the code.
--
Mats