Newbie question - displaying trivia questions at random

P

philbo30

Caveat: I know very little about C; please exuse my current ignorance.

Here's what I need to do:

I have a list of 10 quotations that I want to display, at random each
time my DOS application is run. Currently, I have them commented out,
since I don't know how to get them working. Here's an example of how
they look right now (just 2 for reference):


/*Trivia Question 1
printf("Today's Trivia\n");
printf("Did you know that the\n");
printf("Sears Tower is over 500\n");
printf("meters tall and contains 108\n");
printf("floors?\n");
*/

/*Trivia Question 2
printf("Today's Trivia\n");
printf("Did you know that the\n");
printf("Fordham Spire is over 600\n");
printf("meters tall and contains 124\n");
printf("floors?\n");
*/

Because I have limited output space to work with, I need them to
display in the manner shown above. (i.e. no more than 4 to 5 words per
line).

I assume the basic process is something to the effect of:
1. Associate each of the 10 trivia questions with an integer
2. Upon running the .exe, generate a random integer from the list and
then
3. Display the trivia question associated with the random integer
4. Do again

It really boils down to # 3, displaying each trivia question,
consisting of 5 to 7 lines, as a unit, at random, each time application
runs.

In advance, thank you for any information you may be able to provide or
any direction you may be able to point me in. Please note that this
will be running on an embedded system, so the most simple approach, as
usual, is the best, I think.

Philbo
 
R

Richard Heathfield

philbo30 said:
Caveat: I know very little about C; please exuse my current ignorance.

Here's what I need to do:

I have a list of 10 quotations that I want to display, at random each
time my DOS application is run.

If you mean MS-DOS, you have lots of memory - tens of kilobytes - to play
with, so this should be trivial.
Because I have limited output space to work with, I need them to
display in the manner shown above. (i.e. no more than 4 to 5 words per
line).

Store them as an array of const char *, e.g.

const char *trivia[] =
{
"I knew a man with a wooden leg called Smith",
"Peter Piper picked a peck of pickled pepper",
"foo bar baz quux whatever blah blah"
};

Let the maximum display width be N.

Write the intro:

puts("Today's Trivia");
puts("Did you know that");

Now pick a trivium at random (see FAQ for how to get a random number in the
right range).

Point to the beginning of the trivium.
Find the length of the trivium.
For as long as that length exceeds N:
Find the last possible displayable character, N bytes on from the
beginning of the text that hasn't yet been displayed.
Search backward from that point until you find a space or hit the
beginning of the string.
Display everything up to that point.
Point to the beginning of the text that hasn't yet been displayed.
Subtract from your length counter the number of characters you
just displayed.
Rof
Display the remainder of the trivium.

In advance, thank you for any information you may be able to provide or
any direction you may be able to point me in. Please note that this
will be running on an embedded system, so the most simple approach, as
usual, is the best, I think.

The simplest approach would be to hire a C programmer to do this for you.
This really is very basic stuff.
 
S

Simon Biber

philbo30 said:
Caveat: I know very little about C; please exuse my current ignorance.

Here's what I need to do:

I have a list of 10 quotations that I want to display, at random each
time my DOS application is run. Currently, I have them commented out,
since I don't know how to get them working. Here's an example of how
they look right now (just 2 for reference):

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
/* set the seed of the pseudo-random
number generator from the current time */

srand(time(NULL));

/* select a block of code based
on a random number from 0 to 9 */

switch(rand() % 10)
{
case 0:
printf("Today's Trivia\n");
printf("Did you know that the\n");
printf("Sears Tower is over 500\n");
printf("meters tall and contains 108\n");
printf("floors?\n");

break;
case 1:
printf("Today's Trivia\n");
printf("Did you know that the\n");
printf("Fordham Spire is over 600\n");
printf("meters tall and contains 124\n");
printf("floors?\n");

break;
case 2:
...
}
return 0;
}
 
P

philbo30

Simon said:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
/* set the seed of the pseudo-random
number generator from the current time */

srand(time(NULL));

/* select a block of code based
on a random number from 0 to 9 */

switch(rand() % 10)
{
case 0:


break;
case 1:


break;
case 2:
...
}
return 0;
}

Thanks; this works wonderfully. Now, there's have another problem to
solve that may be more difficult. First, here's the code as it is now:

int trivia (void)
{
srand((unsigned)time(NULL)); //set seed of prandom numb. generator
from time
switch(rand() % 2); //select code block based on random number

{
case 0:
printf("Today's Trivia\n");
printf("Did you know that the\n");
printf("Sears Tower is over 500\n");
printf("meters tall and contains 108\n");
printf("floors?\n");
break;

case 1:
printf("Today's Trivia\n");
printf("Did you know that the\n");
printf("Fordham Spire is over 600\n");
printf("meters tall and contains 124\n");
printf("floors?\n");
break;
}

return 0;
}

The problem is that the "cases" need to change fairly regularly in
order to educate the system users with pertinent facts. So, the cases
need to come from an external config file rather than being compiled
into the application. Any ideas?
 
B

Ben Bacarisse

Thanks; this works wonderfully. Now, there's have another problem to
solve that may be more difficult. First, here's the code as it is now:

int trivia (void)
{
srand((unsigned)time(NULL)); //set seed of prandom numb. generator
from time
switch(rand() % 2); //select code block based on random number

{
case 0:
printf("Today's Trivia\n");
printf("Did you know that the\n");
printf("Sears Tower is over 500\n");
printf("meters tall and contains 108\n");
printf("floors?\n");
break;

case 1:
printf("Today's Trivia\n");
printf("Did you know that the\n");
printf("Fordham Spire is over 600\n");
printf("meters tall and contains 124\n");
printf("floors?\n");
break;
}

return 0;
}

The problem is that the "cases" need to change fairly regularly in
order to educate the system users with pertinent facts. So, the cases
need to come from an external config file rather than being compiled
into the application. Any ideas?

I was about to say: this kind of thing is much easier in (for example)
Perl, but then I thought, actually it is simple in C as well and that
suites your situation (adding code to a DOS program) much better.

I needed something to help me get to sleep so I wrote:

#include <limits.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>

int scan_paras(FILE *fp, int print_number)
{
enum state {
in_para, end_of_line, end_of_para
};

enum state last_state = end_of_para;
enum state input_state;
int c, paragraph = 0;

while ((c = fgetc(fp)) != EOF && paragraph <= print_number) {
switch (last_state) {
case in_para:
input_state = c == '\n' ? end_of_line : last_state;
break;
case end_of_line:
input_state = c == '\n' ? end_of_para : in_para;
break;
case end_of_para:
input_state = c == '\n' ? last_state : in_para;
break;
}

if (input_state == in_para && last_state == end_of_para)
paragraph += 1;

if (paragraph == print_number)
fputc(c, stdout);

last_state = input_state;
}
return paragraph;
}

int main(int argc, char **argv)
{
int n_paras;
FILE *tip_file = NULL;

if (argc != 2 || (tip_file = fopen(argv[1], "r")) == NULL) {
fprintf(stderr, "Please provide one readable text file
argument.\n");
return EXIT_FAILURE;
}
srand((unsigned)time(NULL));
n_paras = scan_paras(tip_file, INT_MAX);

if (fseek(tip_file, 0L, SEEK_SET) != 0) {
fprintf(stderr, "The file %s could be re-read.\n", argv[1]);
return EXIT_FAILURE;
}
(void)scan_paras(tip_file, rand() % n_paras + 1);
return EXIT_SUCCESS;
}

The file of tips just uses multiple newlines (or DOS equivalents) to
separate each tip. It reads the file twice, so it will not work on
non-seekable streams but I don't think that will worry you.

Try to excuse the absence of comments, it is late here after all.
Does anyone else use coding C as a soporific?
 
G

goose

philbo30 said:
Simon Biber wrote:
Thanks; this works wonderfully. Now, there's have another problem to
solve that may be more difficult. First, here's the code as it is now:

int trivia (void)
{
srand((unsigned)time(NULL)); //set seed of prandom numb. generator
from time
switch(rand() % 2); //select code block based on random number

{
case 0:
printf("Today's Trivia\n");
printf("Did you know that the\n");
printf("Sears Tower is over 500\n");
printf("meters tall and contains 108\n");
printf("floors?\n");
break;

case 1:
printf("Today's Trivia\n");
printf("Did you know that the\n");
printf("Fordham Spire is over 600\n");
printf("meters tall and contains 124\n");
printf("floors?\n");
break;
}

return 0;
}

The problem is that the "cases" need to change fairly regularly in
order to educate the system users with pertinent facts. So, the cases
need to come from an external config file rather than being compiled
into the application. Any ideas?

Here is a full program that will store and display
(not randomly) the trivia. Below this is a sample
trivia file. Basically, this works by reading in the
file and storing each trivia in an array of char *.

When loading the file, I first count the number of
trivia elements there are, then allocate an array
for all. For each element of the array (each trivia)
I count the number of characters that need to be
stored and allocate memory for that element and then
store the trivia as a simple string.

Any trivia can be then retrieved using the trivia()
function. The external file that is read in has
to be in a specific format: a % followed by the
text of the trivia. The end of a trivia is either
a % or end of file.

Freeing the array is an exercise left to the
reader :). I also believe that main() is easy enough
to modify to display random trivia, instead of all
trivia (I displayed all to test that all worked).

-------------------code.c---------------------
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

static char **text = NULL;
static int num_items = 0;

static char *trivia (int index)
{
if (text) {
return text[index % num_items];
} else {
return NULL;
}
}

#define DELIM '%'
static int load_data (FILE *in)
{
int c;
int i, j;

/* find the number of arrays we need */
fseek (in, 0, SEEK_SET);
while ((c = fgetc (in))!=EOF) {
if (c==DELIM) num_items++;
}
if (!num_items) return EXIT_FAILURE;

/* allocate our array */
text = malloc (num_items * sizeof *text);
if (!text) return EXIT_FAILURE;

/* find the first record */
fseek (in, 0, SEEK_SET);
while ((c = fgetc (in))!=DELIM && c!=EOF)
;

/* read in each piece of trivia text */
for (i=0; i<num_items; i++) {
fpos_t place;
int num_chars = 0;

fgetpos (in, &place);
while ((c = fgetc (in))!=DELIM && c!=EOF) {
num_chars++;
}
text = malloc (num_chars + 1);
if (!text) {
num_items = i;
return EXIT_SUCCESS; /* we'd keep all that we already stored
*/
}
fsetpos (in, &place);
c = fgetc (in);
for (j=0; j<num_chars; j++) {
if ((c = fgetc (in))!=EOF) {
text[j] = c;
} else {
break;
}
}
text[j-1] = 0;
}
return EXIT_SUCCESS;
}

#define TRIVIA_FILE ("trivia.txt")
int main(void)
{
FILE *trivia_file = fopen (TRIVIA_FILE, "r");
int i;

if (!trivia_file) {
printf ("cannot open %s file\n", TRIVIA_FILE);
return EXIT_FAILURE;
}
if (load_data (trivia_file)!=EXIT_SUCCESS) {
puts ("cannot load data from trivia.txt\n");
return EXIT_FAILURE;
}
printf ("number of items = %i\n", num_items);
for (i=0; i<num_items; i++) {
char *display = trivia (i);
printf ("Trivia #%i:\n%s\n", i, display);
}
return 0;
}
-------------------code.c---------------------
-------------------trivia.txt---------------------
%
The quick brown fox
jumped over the
lazy sleeping god.
%
To beer, or not to
beer, what was the
question?
%
A programmer named Lenore
thought unix and C a bore,
She tried VB
and the language called D,
Now she sells C shells by the C shore
%
My Kingdom! My kingdom for
a compiler
%
This trivia copyrighted by
the little green men in my head.
%
Deja Moot: This happened before,
and I didn't care then either.

-------------------trivia.txt---------------------


goose,
 
A

av

On 7 Aug 2006 04:10:47 -0700, goose wrote:

this run here too
//

int P(char* , ... ); /* print console */

#define F for
#define R return
#define W while
#define G goto


#define _EoF (1)
#define _EoM (2)
#define _NuL (4)
#define _UnG (8)

int getline_state=0, getline_len=0;

void getline_error(void)
{if(_EoF&getline_state) P("Incontrato nel file EOF\n");
if(_EoM&getline_state) P("Memoria insufficiente \n");
if(_NuL&getline_state) P("Argomenti di getline sbagliati\n");
if(_UnG&getline_state) P("Errore lettura dal file\n");
if( 16 &getline_state) P("Delimitatore per getline troppo lungo\n");
}


// "s" is zero or point to "malloc" memory
// delimitator have to have the len<8
char*
getliner_m(FILE_m* file, char* s, char* delimitator)
{int c, i, w, ch, len;
char *k, *t="\n", *tt;
// //////////////////////////////
getline_state=0; getline_len=0;
if(file==0)
{getline_state=_NuL; return 0;}
// il delimitatore sepre !=0
if(delimitator!=0||*delimitator==0)
{t=delimitator;}
w=14;
if( (k=(char*) realloc_m(s, w+2))== 0)
G via;
else s=k;
tt=t; i=0;
W(1)
{if( i>=w ) // w= 14, 30, 62, 126
{w=2*w+2; // 16, 32, 64, 128
if((k=(char*) realloc_m(s, w+2))== 0)
{
via:; getline_state |= _EoM;
via0:; free_m(s);
R 0;
}
else s=k;
}
if((c=fgetc_m(file))==EOF)
{ getline_state|= _EoF; break;}
if(c==*t)
{len=0;
W( *++t && (ch=fgetc_m(file))!=EOF && *t==ch)
if( ++len>=8 ){ getline_state|=16; G via0; }
if(*t==0) break; // find delimitator
if(ch!=EOF) --t; // not find
ungetc_m(ch, file); // i can ungetc 1 EOF
if( cf() == 1)
{
via1:; getline_state|= _UnG; G via0;
}
W( t>tt )
{ungetc_m(*t, file);
if( cf() == 1) G via1;
--t;
}
// if here => t==tt
}
s[i++]=(char) c;
}
s='\0';
getline_len=i;
R s;
}


#include "winb.h"
// in winb.h there are definition for all functions
// here

static char **text =0;
static int num_items =0;

static char* trivia(int index)
{if(text) R text[index%num_items];
else R "Null ";
}

#define DELIM '%'

static int load_data(FILE_m *in)
{char **t;
int c, i, j, w;
int place, num_chars;

w=14;
/* allocate our array */
text= (char**) malloc_m(w * sizeof *text);
if(text==0) R 0;

/* find the first record */
fseek_m(in, 0, SEEK_SET);

/* read in each piece of trivia text */
F( i=0; ; ++i)
{if(i>=w)
{w=2*w+2;
t=(char**) realloc_m(text, (w+2) * sizeof *t );
if(t==0){P("Memoria insufficiente\n"); --i; break;}
text=t;
}
text=getliner_m(in, 0, "%\x0D\n"); // DILIM==%\13\n
if(text==0) {getline_error(); break; }
if(getline_state&1) break;
}
num_items=i+1;
R 1;
}

char *trivia_f = "trivia.txt";

int main(void)
{int i;
FILE_m *trivia_file=fopen_m(trivia_f , "rb" );
// i don't have text mode

if(trivia_file==0)
{P("Can not open %s file\x0D\n", trivia_f ); R 1;}
if(load_data(trivia_file)==0)
{P("Can not load data from %s file\x0D\n", trivia_f );
fclose_m(trivia_file);
R 0;
}
P("Number of items = %i\x0D\n", num_items);
F( i=0; i<num_items; ++i)
P("Trivia #%i:\x0D\n%s\x0D\n", i, trivia(i));

F(i=0; i<num_items; ++i) free_m(text);
free_m(text);
fclose_m(trivia_file);
R 0;
}

the result of "goose > file"
Number of items = 6
Trivia #0:
The quick brown fox
jumped over the
lazy sleep god.

Trivia #1:
To beer, or not to
beer, what was the
question?

Trivia #2:
A programmer named Lenore
thought Unix and C a bore,
She tried VB
and the language called D,
Now she sells C shells by the C shore

Trivia #3:
My Kingdom! My Kingdom for
a compiler

Trivia #4:
This trivia copyrighted by
the little green men in my head.

Trivia #5:
Deja Moot: This happened before,
and I didn't care then either.
%MEMORIA DINAMICA LIBERATA Tot=0.0080 Mb
belive it or not
 
R

Richard Heathfield

av said:
On 7 Aug 2006 04:10:47 -0700, goose wrote:

this run here too
//

int P(char* , ... ); /* print console */

#define F for
#define R return
#define W while
#define G goto


#define _EoF (1)

This program invades implementation namespace. Please return your banana to
the basket.
 
F

Flash Gordon

av said:
On 7 Aug 2006 04:10:47 -0700, goose wrote:

You've provided no context beyond who you are replying to. This means
we've no idea why you are posting this code.
this run here too
//

int P(char* , ... ); /* print console */

Stupid function name making it needlessly hard to read.
#define F for
#define R return
#define W while
#define G goto

Stupid macros to make it needlessly hard to read. Don't do this if you
want anyone else to bother reading your code.
#define _EoF (1)
#define _EoM (2)
#define _NuL (4)
#define _UnG (8)

The above macros are all in the implementation namespace so your code is
needlessly non-conforming.

if( (k=(char*) realloc_m(s, w+2))== 0)

Calling realloc without a prototype in scope invokes undefined behaviour
and DOES break on MODERN platforms. Casing the return value only hides a
diagnostic that the compiler would otherwise be required to provide, it
does not solve the problem or make it work on platforms where it breaks.

#include "winb.h"

<snip>

You've not provided winb.h so we've no idea what it contains.

You've made the code hard enough to read that most people are unlikely
to bother reading it. I've not bothered reading all the code I snipped.
All I know is that I would just throw that code away if someone gave it
to me to do anything with.
 
K

Keith Thompson

av said:
On 7 Aug 2006 04:10:47 -0700, goose wrote:

this run here too
//

int P(char* , ... ); /* print console */

#define F for
#define R return
#define W while
#define G goto


#define _EoF (1)
#define _EoM (2)
#define _NuL (4)
#define _UnG (8)
[snip]

When you stopped using the name "RoSsIaCrIiLoIA" (you're the same
person, right?), I hoped it was because you were trying to establish a
new identity, and that you were going to stop posting really really
stupid code.

I am not going to waste my time reading anything that uses your silly
and obscure one-letter abbreviations to replace perfectly clear
keywords. Please don't waste your time posting this stuff.
 
A

av

On 7 Aug 2006 04:10:47 -0700, goose wrote:
// "s" is zero or point to "malloc" memory
// delimitator have to have the len<8
char*
getliner_m(FILE_m* file, char* s, char* delimitator)
{int c, i, w, ch, len;
char *k, *t="\n", *tt;
// //////////////////////////////
getline_state=0; getline_len=0;
if(file==0)
{getline_state=_NuL; return 0;}
// il delimitatore sepre !=0
if(delimitator!=0||*delimitator==0)
{t=delimitator;}
w=14;
if( (k=(char*) realloc_m(s, w+2))== 0)
G via;
else s=k;
tt=t; i=0;
W(1)
{if( i>=w ) // w= 14, 30, 62, 126
{w=2*w+2; // 16, 32, 64, 128
if((k=(char*) realloc_m(s, w+2))== 0)
{
via:; getline_state |= _EoM;
via0:; free_m(s);
R 0;
}
else s=k;
}
if((c=fgetc_m(file))==EOF)
{ getline_state|= _EoF; break;}
if(c==*t)
{len=0;
W( *++t && (ch=fgetc_m(file))!=EOF && *t==ch)
if( ++len>=8 ){ getline_state|=16; G via0; }
if(*t==0) break; // find delimitator
if(ch!=EOF) --t; // not find

"if(ch!=EOF) --t;" seems wrong better "--t"
ungetc_m(ch, file); // i can ungetc 1 EOF
if( cf() == 1)
{
via1:; getline_state|= _UnG; G via0;
}
W( t>tt )
{ungetc_m(*t, file);
if( cf() == 1) G via1;
--t;
}
// if here => t==tt
}
s[i++]=(char) c;
}
s='\0';
getline_len=i;
R s;
}
 
G

goose

av said:
On 7 Aug 2006 04:10:47 -0700, goose wrote:

this run here too
//

int P(char* , ... ); /* print console */

#define F for
#define R return
#define W while

av, get your damn attributions correct! I didn't
this crap!!!


goose,
 
A

av

char*
getliner_m(FILE_m* file, char* s, char* delimitator)
{int c, i, w, ch, len;
char *k, *t="\n", *tt;
// //////////////////////////////
getline_state=0; getline_len=0;
if(file==0)
{getline_state=_NuL; return 0;}
// il delimitatore sepre !=0
if(delimitator!=0||*delimitator==0)
{t=delimitator;}

if(delimitator!=0 && *delimitator!=0)
{t=delimitator;}
 
A

av

av wrote:

Calling realloc without a prototype in scope invokes undefined behaviour
and DOES break on MODERN platforms.

it is not "realloc" it is "realloc_m"; so if i have realloc_m is all
ok
 
A

av

char*
getliner_m(FILE_m* file, char* s, char* delimitator)
{int c, i, w, ch, len;
char *k, *t="\n", *tt;
// //////////////////////////////
getline_state=0; getline_len=0;
if(file==0)
{getline_state=_NuL; return 0;}
// il delimitatore sepre !=0
if(delimitator!=0||*delimitator==0)
{t=delimitator;}

if(delimitator!=0 && *delimitator!=0)
{t=delimitator;}
 
A

av

av wrote:

Calling realloc without a prototype in scope invokes undefined behaviour
and DOES break on MODERN platforms.

it is not "realloc" it is "realloc_m"; so if i have realloc_m is all
ok
 
A

av

this is my "C++" version

#include "winb.h"

static char **text =0;
static int num_items =0;

int resize(void)
{static int w=0;
char **t;
w = (w==0? 14: 2*w+2);
t=(char**) realloc_m(text,(w+2)*(sizeof *t));
if(t==0) R 0;
text=t;
R w;
}

void free_v(void)
{int i;
if(text)
{F(i=0; i<num_items; ++i)
free_m(text);
free_m(text);
}
}

static char* trivia(int index)
{if(text) R text[index%num_items];
else R "Null ";
}

#define DELIMITATORE "%\x0D\n"

static int load_data(istream& in)
{int i, w;
// ///////////////
/* find the first record */
i=fseek_m(in.f, 0, SEEK_SET);
if(i!=0) R 0;
/* read in each piece of trivia text */
F( i=0, w=0; ;)
{label:
if(i>=w)
{w=resize();
if(w<=0){P("Memoria insufficiente\n"); break;}
else G label;
}
text=in.getline(0, DELIMITATORE); // DILIM==%\13\n
if(text==0) {getline_error(); break; }
++i;
if(getline_state&1) break;
}
num_items=i;
R i;
}

char *name="trivia.txt";

int main(void)
{int i;
istream triviatxt(name);

if(triviatxt==0)
{P("Can not open %s file\x0D\n", name); R 1;}
if(load_data(triviatxt)==0)
{P("Can not load data from %s file\x0D\n", name );
// i'm forgetting something?
R 1;
}
P("Number of items = %i\x0D\n", num_items);
F( i=0; i<num_items; ++i)
P("Trivia #%i:\x0D\n%s\x0D\n", i, trivia(i));
exit_m(0); // exit here free all dinamic memory
// close all file and call "exit(0);"
// it seems i have not include "stdlib.h"
// but that function link good and free
// all global object that compiler has
// in the prog
}

where trivia.txt is
"The quick brown fox
jumped over the
lazy sleep god.
%
To beer, or not to
beer, what was the
question?
%
A programmer named Lenore
thought Unix and C a bore,
She tried VB
and the language called D,
Now she sells C shells by the C shore
%
My Kingdom! My Kingdom for
a compiler
%
This trivia copyrighted by
the little green men in my head.
%
Deja Moot: This happened before,
and I didn't care then either."

the result with "prog> file.txt"

Number of items = 6
Trivia #0:
The quick brown fox
jumped over the
lazy sleep god.

Trivia #1:
To beer, or not to
beer, what was the
question?

Trivia #2:
A programmer named Lenore
thought Unix and C a bore,
She tried VB
and the language called D,
Now she sells C shells by the C shore

Trivia #3:
My Kingdom! My Kingdom for
a compiler

Trivia #4:
This trivia copyrighted by
the little green men in my head.

Trivia #5:
Deja Moot: This happened before,
and I didn't care then either.
MEMORIA DINAMICA LIBERATA Tot=0.0080 Mb
 

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

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,280
Latest member
BGBBrock56

Latest Threads

Top