codice:
#include <cstdlib>
#include <iostream>
#include <fstream>
#define MAXLEN 100  //lunghezza massima delle stringhe di nomi,cognimi,domini.
struct chunk
{
   chunk()
   {
      data = NULL;
      next = NULL;
   }
   char* data;
   chunk* next;
};
struct list //struttura per le liste di valori per campo
{
       list() //inizializza la lista
       {
          first = NULL;
          count = 0;
       }
       chunk* first;
       chunk* last;
       int count; //numero di valori nella lista
       char* FindString(int ID) //trova il valore con id ID
       {
             int i = 0;
             chunk* c = first;
             while(i < ID) {c = c->next; i++;}
             return(c->data);
       }
       void AddValue(char* value)
       {
            chunk* c = new chunk;
            memcpy(c->data,value,strlen(value)+1);
            if(first == NULL) {first = c; last = first;}
            else {last->next = c; last = last->next;}
            count++;
       }
};
list* CreaListaDaFile(char* fname)
{
      list* lista = new list;
      FILE* file = fopen(fname);
      char c[2];
      char str[MAXLEN+1];
      int pos = 0;
      while(!feof(file))
      {
          fread(c,sizoef(char),2,file);
          if(c[0] == 13 && c[1] == 10) // a capo!
          {
             str[pos] = NULL;
             lista->AddValue(str);
             pos = 0;
          }
          else
          {
              fseek(file,-2,SEEK_CUR);
              fread(str+pos,sizeof(char)1,file);
              pos++;
          }
      }
      fclose(file);
      return(lista);
}
using namespace std;

int main(int argc, char *argv[])
{
    list* nomi = CreaListaDaFile("C:/nomi.txt");
    list* cognomi = CreaListaDaFile("C:/cognomi.txt");
    list* domini = CreaListaDaFile("C:/domini.txt");
    //nomi.cognomi.domini
    int campi[3]; //creo 3 campi, ognuno è un numero che va da 0 all'indice dell'ultimo valore della sua lista (==sua_lista.count-1, se diamo al primo indice 0)
    campi[0] = 0;
    campi[1] = 0;
    campi[2] = 0; //ho messo l'indice di ogni campo al primo della loro lista.
    //campo0 è quello più a sinistra, poi viene 1 e 2.
    while(true)
    { //finchè il campo più a sinistra non ha raggiunto il fondo della sua lista
      cout << nomi->FindString(campi[0]) << "." << cognomi->FindString(campi[1]) << "@" << domini->FindString(campi[2]) << endl;
      campi[2]++;
      if(campi[2] == domini->count)
      {
         campi[2] = 0;
         campi[1]++;
         if(campi[1] == cognomi->count)
         {
             campi[1] = 0;
             campi[0]++;
             if(campi[0] == nomi->count)
             {
                 break;
             }
         }
      }
    }
    system("PAUSE");
    return EXIT_SUCCESS;
}
Dovrebbe andare ma non ho controllato