views:

120

answers:

5

Hi,

I want to store data in C in tabular format. I am having difficulty in relating the following. Can someone help?

For example: I want to store the follwong entries, then what should be the ideal way of storing in C?

   IP Address              Domain Name  
 1.)    10.1.1.2                www.yahoo.com  
 2.)    20.1.1.3                www.google.com

Should i use structures? Say for example?

struct table
{
    unsigned char ip address;
    char domain_name[20];
};

If not, please clarify?

+2  A: 

The method of storage depends at least partially on what you're going to do with the information. If it's simply to read it in and then print it out again, you could process it strictly as text.

However, network programs often make use of this type of data. See the structures in the system header files netinet/in.h, arpa/inet.h, and sys/socket.h Or see the man page for inet_aton()

wallyk
+1  A: 

Structures are the way to go. Use sufficiently sized arrays. IPV4 addresses take 16 chars and domain names take a maximum of 255 chars.

struct table
{
    char ip_addr[16];
    char domain_name[255];
};
Amarghosh
Why do you think using pointers is a good idea?
anon
@Neil Domain name lengths won't always be within 20 - they vary from `bit.ly` to very long ones, and I guess allocating memory in heap as and when required would be better than an array[MAX_LENGTH] that would eat stack space (it looked like he has a lot of items - from the fact that he considered calling it `table`)
Amarghosh
@Neil Can you tell me why it is not a good idea?
Amarghosh
I'd use a 32-bit integer for the IP address unless you need to support IPv6 as well. In that case, I'd use a union. Using a fix-sized char array--with 254 bytes instead of 20--would prevent the need for careful memory management.
Judge Maygarden
I wasn't aware of the 254 limitation on the length of domain names. Btw, if you want another reason why you shouldn't use pointers, check this http://stackoverflow.com/questions/2764475/fragmentation-error-while-executing-c-program
Amarghosh
+3  A: 

You probably mixing two different questions:

  1. How to organize data in your program (in-memory) - this is the part about using structures.
  2. How to serialize data, that is to store it in external storage e.g. in file. This is the part about "tabular" format that implies text with fields delimited by tabs.

If IP and domain often come together in your program then it is reasonable to use structure or class (in C++) for that. Regarding your example I do not know restrictions on domain name lenght but "20" would be definitely insufficient. I'd suggest using dynamically allocated strings here. For storing IP (v4) address you may use 32 bit unsigned int - char is insufficient. Do you intend to support IP v6 also? then you need 128 bit for address.

In C (and C++) there is no built-in serialization facility like one in virtually every dynamic (or "managed") language like C#, Java, Python. So by defining a structure you do not automatically get methods for writing/reding your data. So you should use some library for serialization or write your own for reading/writing your data.

Petr Gladkikh
A: 

Unfortunately I cannot make comments. But in respect to Amarghosh's answer, this problem would be perfectly solved using fixed length arrays for the fields since both sets (if domain is top-level only) of data are of limited length (15 characters for the ip address [assuming IPv4], and there is a 63 character ascii limit per label for domain names.)

NFA
Do you have a reference for the 63 character limit? I thought it was 255 (including the NULL terminator).
Judge Maygarden
After some research you are probably right. However most domain name registrars connected with ICANN limit it to 63 characters per label. Total domain name cannot exceed 255 characters though.
NFA
A: 

There are two issues in representing tabular data:
1. Representing a row
2. Representing many rows.

In your example, the row can be represented by:

struct Table_Record
{
  unsigned char ip_address[4];
  char          domain_name[MAX_DOMAIN_LENGTH];
};

I've decided to use a fixed field length for the domain name. This will make processing simpler.

The next question is how to structure the rows. This is a decision you will have to make. The simplest suggestion is to use an array. However, an array is a fixed size and needs to be reallocated if there are more entries than the array size:

struct Table_Record    table[MAX_ROWS];

Another data structure for the table is a list (single or double, your choice). Unfortunately, the C language does not provide a list data structure so you will have either write your own or obtain a library.

Alternative useful data structures are maps (associative arrays) and trees (although many maps are implemented using trees). A map would allow you to retrieve the value for a given key. If the key is the IP address, the map would return the domain name.

If you are going to read and write this data using files, I suggest using a database rather than writing your own. Many people recommend SQLite.

Thomas Matthews