Remove extra blanks

R

Registered User

Hi experts,
I'm trying to write a program that replaces two or more consecutive
blanks in a string by a single blank.

Here's what I did:

#include <stdio.h>
#include <string.h>
#define MAX 80

int main()
{
char s[MAX];
int i, j;
fgets(s, MAX, stdin);
i=strlen(s);
while(i)
{
while (s[--i]!=' ' && i>0) /*Find the last space*/
;
j=i;
while (s[--j]==' ' && j>0) /*Go to the last non-space*/
; /*char before s*/

if (s[j]!=' ')
j++; /*Increment j so that s[j] is a space*/

if (j<i) /*If extra spaces have been found, remove*/
while (s) /*them by left shifting */
s[++j]=s[++i]; /*the characters on the right*/

i=j;
}
puts(s);

return 0;
}

The program works fine, but I have a feeling that I've made it
unnecessarily complicated.


Can anyone suggest ways on which I can improve upon the code? Is there
a better algorithm?
 
C

CBFalconer

Registered said:
I'm trying to write a program that replaces two or more consecutive
blanks in a string by a single blank.

Here's what I did:

#include <stdio.h>
#include <string.h>
#define MAX 80

int main()
{
char s[MAX];
int i, j;
fgets(s, MAX, stdin);
i=strlen(s);
while(i)
{
while (s[--i]!=' ' && i>0) /*Find the last space*/
;
j=i;
while (s[--j]==' ' && j>0) /*Go to the last non-space*/
; /*char before s*/

if (s[j]!=' ')
j++; /*Increment j so that s[j] is a space*/

if (j<i) /*If extra spaces have been found, remove*/
while (s) /*them by left shifting */
s[++j]=s[++i]; /*the characters on the right*/

i=j;
}
puts(s);

return 0;
}

The program works fine, but I have a feeling that I've made it
unnecessarily complicated.

Can anyone suggest ways on which I can improve upon the code? Is there
a better algorithm?


Try this. Notice the absence of string buffers. Should work until
you get over 32767 consecutive blanks.

#include <stdio.h>
int main(void)
{
int blanks, ch;

blanks = 0;
while (EOF != (ch = getchar())) {
if (' ' == ch) {
++blanks;
if (1 == blanks) putchar(' ');
}
else {
putchar(ch);
blanks = 0;
}
}
return 0;
}
 
R

Richard

Registered User said:
Hi experts,
I'm trying to write a program that replaces two or more consecutive
blanks in a string by a single blank.

Here's what I did:

#include <stdio.h>
#include <string.h>
#define MAX 80

int main()
{
char s[MAX];
int i, j;
fgets(s, MAX, stdin);
i=strlen(s);
while(i)
{
while (s[--i]!=' ' && i>0) /*Find the last space*/
;
j=i;
while (s[--j]==' ' && j>0) /*Go to the last non-space*/
; /*char before s*/

if (s[j]!=' ')
j++; /*Increment j so that s[j] is a space*/

if (j<i) /*If extra spaces have been found, remove*/
while (s) /*them by left shifting */
s[++j]=s[++i]; /*the characters on the right*/

i=j;
}
puts(s);

return 0;
}

The program works fine, but I have a feeling that I've made it
unnecessarily complicated.


Can anyone suggest ways on which I can improve upon the code? Is there
a better algorithm?


Much faster & efficient IMO (in most cases I would think) to
malloc a new string, copy the original one into it and then update the
original in place - no repeated shuffling.

strcpy(refCopy,refStr)
char *d=refStr; /*destination*/
char *s=refCopy; /*original string copy - source*/
while(*d++=(ch=*s++))
if(ch==' '){
while((ch=*s++)&&(ch==' ')); /*gobble up following spaces
if (!(*d++=ch)) /* store first non space */
break;
}

Not tested, but you will get the idea.
 
J

Joe Wright

CBFalconer said:
Registered said:
I'm trying to write a program that replaces two or more consecutive
blanks in a string by a single blank.

Here's what I did:

#include <stdio.h>
#include <string.h>
#define MAX 80

int main()
{
char s[MAX];
int i, j;
fgets(s, MAX, stdin);
i=strlen(s);
while(i)
{
while (s[--i]!=' ' && i>0) /*Find the last space*/
;
j=i;
while (s[--j]==' ' && j>0) /*Go to the last non-space*/
; /*char before s*/

if (s[j]!=' ')
j++; /*Increment j so that s[j] is a space*/

if (j<i) /*If extra spaces have been found, remove*/
while (s) /*them by left shifting */
s[++j]=s[++i]; /*the characters on the right*/

i=j;
}
puts(s);

return 0;
}

The program works fine, but I have a feeling that I've made it
unnecessarily complicated.

Can anyone suggest ways on which I can improve upon the code? Is there
a better algorithm?


Try this. Notice the absence of string buffers. Should work until
you get over 32767 consecutive blanks.

#include <stdio.h>
int main(void)
{
int blanks, ch;

blanks = 0;
while (EOF != (ch = getchar())) {
if (' ' == ch) {
++blanks;
if (1 == blanks) putchar(' ');
}
else {
putchar(ch);
blanks = 0;
}
}
return 0;
}

Or maybe..

#include <stdio.h>
int main(void) {
int ch, last = 0;
while ((ch = getchar()) != EOF) {
if (!(ch == ' ' && last == ch))
putchar(ch);
last = ch;
}
return 0;
}
 
R

Richard

Joe Wright said:
CBFalconer said:
Registered said:
I'm trying to write a program that replaces two or more consecutive
blanks in a string by a single blank.

Here's what I did:

#include <stdio.h>
#include <string.h>
#define MAX 80

int main()
{
char s[MAX];
int i, j;
fgets(s, MAX, stdin);
i=strlen(s);
while(i)
{
while (s[--i]!=' ' && i>0) /*Find the last space*/
;
j=i;
while (s[--j]==' ' && j>0) /*Go to the last non-space*/
; /*char before s*/

if (s[j]!=' ')
j++; /*Increment j so that s[j] is a space*/

if (j<i) /*If extra spaces have been found, remove*/
while (s) /*them by left shifting */
s[++j]=s[++i]; /*the characters on the right*/

i=j;
}
puts(s);

return 0;
}

The program works fine, but I have a feeling that I've made it
unnecessarily complicated.

Can anyone suggest ways on which I can improve upon the code? Is there
a better algorithm?

Try this. Notice the absence of string buffers. Should work until
you get over 32767 consecutive blanks.
#include <stdio.h>
int main(void)
{
int blanks, ch;
blanks = 0;
while (EOF != (ch = getchar())) {
if (' ' == ch) {
++blanks;
if (1 == blanks) putchar(' ');
}
else {
putchar(ch);
blanks = 0;
}
}
return 0;
}

Or maybe..

#include <stdio.h>
int main(void) {
int ch, last = 0;
while ((ch = getchar()) != EOF) {
if (!(ch == ' ' && last == ch))
putchar(ch);
last = ch;
}
return 0;
}


The problem is that I think the OP was only using fgets to get a sample
string - it is therefore not the excercise to simplify the algorithm
using getchar() or whatever.

His spec was to remove excess spaces from a string.

I could be wrong : if not, see other post.

--
 
R

Registered User

Richard said:
Joe Wright said:
CBFalconer said:
Registered User wrote:
I'm trying to write a program that replaces two or more consecutive
blanks in a string by a single blank.

Here's what I did:

#include <stdio.h>
#include <string.h>
#define MAX 80

int main()
{
char s[MAX];
int i, j;
fgets(s, MAX, stdin);
i=strlen(s);
while(i)
{
while (s[--i]!=' ' && i>0) /*Find the last space*/
;
j=i;
while (s[--j]==' ' && j>0) /*Go to the last non-space*/
; /*char before s*/

if (s[j]!=' ')
j++; /*Increment j so that s[j] is a space*/

if (j<i) /*If extra spaces have been found, remove*/
while (s) /*them by left shifting */
s[++j]=s[++i]; /*the characters on the right*/

i=j;
}
puts(s);

return 0;
}

The program works fine, but I have a feeling that I've made it
unnecessarily complicated.

Can anyone suggest ways on which I can improve upon the code? Is there
a better algorithm?
Try this. Notice the absence of string buffers. Should work until
you get over 32767 consecutive blanks.
#include <stdio.h>
int main(void)
{
int blanks, ch;
blanks = 0;
while (EOF != (ch = getchar())) {
if (' ' == ch) {
++blanks;
if (1 == blanks) putchar(' ');
}
else {
putchar(ch);
blanks = 0;
}
}
return 0;
}

Or maybe..

#include <stdio.h>
int main(void) {
int ch, last = 0;
while ((ch = getchar()) != EOF) {
if (!(ch == ' ' && last == ch))
putchar(ch);
last = ch;
}
return 0;
}


The problem is that I think the OP was only using fgets to get a sample
string - it is therefore not the excercise to simplify the algorithm
using getchar() or whatever.

His spec was to remove excess spaces from a string.

Yes, that's what I want to do: remove excess spaces from a given string.
 
A

Andrew Poelstra

Hi experts,
I'm trying to write a program that replaces two or more consecutive
blanks in a string by a single blank.

Here's what I did:

#include <stdio.h>
#include <string.h>
#define MAX 80

int main()
{
char s[MAX];
int i, j;
fgets(s, MAX, stdin);
i=strlen(s);
while(i)
{
while (s[--i]!=' ' && i>0) /*Find the last space*/
;
j=i;
while (s[--j]==' ' && j>0) /*Go to the last non-space*/
; /*char before s*/

if (s[j]!=' ')
j++; /*Increment j so that s[j] is a space*/

if (j<i) /*If extra spaces have been found, remove*/
while (s) /*them by left shifting */
s[++j]=s[++i]; /*the characters on the right*/

i=j;
}
puts(s);

return 0;
}

The program works fine, but I have a feeling that I've made it
unnecessarily complicated.


Well, use spaces instead of tabs. I've replaced yours with two-space
indents. (On USENET, tabs can be filtered out or displayed incorrectly.)
Can anyone suggest ways on which I can improve upon the code? Is there
a better algorithm?

It'd be better to use two strings, an input and an output. That way, you
can make a function that accepts string literals. (String literals are
non-mutable, in case you didn't know.)

If you use two strings, you can simply copy each character until you hit
a space. Then, copy a space, skip to the next non-whitespace character,
and continue as you were.
 
L

lovecreatesbea...

Registered said:
Hi experts,
I'm trying to write a program that replaces two or more consecutive
blanks in a string by a single blank.

Here's what I did:

#include <stdio.h>
#include <string.h>
#define MAX 80

int main()
{
char s[MAX];
int i, j;
fgets(s, MAX, stdin);
i=strlen(s);
while(i)
{
while (s[--i]!=' ' && i>0) /*Find the last space*/
;
j=i;
while (s[--j]==' ' && j>0) /*Go to the last non-space*/
; /*char before s*/

if (s[j]!=' ')
j++; /*Increment j so that s[j] is a space*/

if (j<i) /*If extra spaces have been found, remove*/
while (s) /*them by left shifting */
s[++j]=s[++i]; /*the characters on the right*/

i=j;
}
puts(s);

return 0;
}

The program works fine, but I have a feeling that I've made it
unnecessarily complicated.


Can anyone suggest ways on which I can improve upon the code? Is there
a better algorithm?


just as an alternative,

/*removes extra blanks from a string, replaces two or more consecutive
blanks in a string by a single space.*/
int sglspc(char *s){
int n;
char *p, *p2;

n = 0;
p = s;

while (*p){
if (*p == ' ' && *(p + 1) == *p){
n++;
p2 = p;

while (*p2){
*p2 = *(p2 + 1);
p2++;
}
} else
p++;
}

return n;
}

#include <stdio.h>
#include <string.h>
int main(void){
char s[] = " hello world ";
int n;

printf("%s, %d\n", s, strlen(s));
n = sglspc(s);
printf("%s, %d, (-%d)\n", s, strlen(s), n);

return 0;
}

$ a.out
hello world , 27
hello world , 13, (-14)

$
 
R

Richard

Richard said:
Registered User said:
Hi experts,
I'm trying to write a program that replaces two or more consecutive
blanks in a string by a single blank.

Here's what I did:

#include <stdio.h>
#include <string.h>
#define MAX 80

int main()
{
char s[MAX];
int i, j;
fgets(s, MAX, stdin);
i=strlen(s);
while(i)
{
while (s[--i]!=' ' && i>0) /*Find the last space*/
;
j=i;
while (s[--j]==' ' && j>0) /*Go to the last non-space*/
; /*char before s*/

if (s[j]!=' ')
j++; /*Increment j so that s[j] is a space*/

if (j<i) /*If extra spaces have been found, remove*/
while (s) /*them by left shifting */
s[++j]=s[++i]; /*the characters on the right*/

i=j;
}
puts(s);

return 0;
}

The program works fine, but I have a feeling that I've made it
unnecessarily complicated.


Can anyone suggest ways on which I can improve upon the code? Is there
a better algorithm?


Much faster & efficient IMO (in most cases I would think) to
malloc a new string, copy the original one into it and then update the
original in place - no repeated shuffling.

strcpy(refCopy,refStr)
char *d=refStr; /*destination*/
char *s=refCopy; /*original string copy - source*/
while(*d++=(ch=*s++))
if(ch==' '){
while((ch=*s++)&&(ch==' ')); /*gobble up following spaces
if (!(*d++=ch)) /* store first non space */
break;
}

Not tested, but you will get the idea.


Idiocy alert : you dont even need the copy thus saving fannying around
with mallocs etc. Just set s to be d. This is fine since s is always
the same or, after the first double space, ahead of the destination pointer.

Whoops.


--
 
J

jacob navia

The strtrim function from the lcc-win32 compiler looks like this:
#include <ctype.h>
int strtrim(char *str)
{
char *src = str,*dst = str,*start = str;

while (isspace(*src)) // Skip leading spaces
src++;
do {
// Copy non space chars
while (*src && !isspace(*src))
*dst++ = *src++;
// Here we have either zero or a space
if (*src) {
*dst++ = *src++; // Copy first space
while (isspace(*src) && // Skip the rest
*src != '\n' && *src != '\r')
src++;
}
} while (*src);
// If the last character before a newline is space, delete it.
if (dst != start && isspace(dst[-1]) && dst[-1] != '\n')
dst--;
*dst = 0;
return dst - src;
}
 
F

free4trample

This si as simple as it gets, i think...
Problem with this code is that it adds a SPACE character at the end of
a file.

====================Start paste=======================
#include<stdio.h>
#include<string.h>
#define MAX_LINE_LENGHTH 200
#define MAX_FN_LENGTH 20

int main(void){
char filein[MAX_FN_LENGTH], fileout[MAX_FN_LENGTH],
s1[MAX_LINE_LENGHTH], *s2;
FILE *ff1, *ff2;

printf("Enter input file: ");
scanf("%s",filein);
printf("\nEnter output file: ");
scanf("%s",fileout);
ff1=fopen(filein,"r");
ff2=fopen(fileout,"w");

while(!feof(ff1)){
fgets(s1,MAX_LINE_LENGHTH,ff1);
s2=strtok(s1," ");
fprintf(ff2,"%s ",s2);
while((s2=strtok('\0'," "))!=NULL){
if(s2[strlen(s2)-1]!='\n')
fprintf(ff2,"%s ",s2);
else
fprintf(ff2,"%s",s2);
}
}

fclose(ff1);
fclose(ff2);
return 0;
}
===================End Paste=================
 
R

Registered User

Richard said:
Richard said:
Registered User said:
Hi experts,
I'm trying to write a program that replaces two or more consecutive
blanks in a string by a single blank.

Here's what I did:

#include <stdio.h>
#include <string.h>
#define MAX 80

int main()
{
char s[MAX];
int i, j;
fgets(s, MAX, stdin);
i=strlen(s);
while(i)
{
while (s[--i]!=' ' && i>0) /*Find the last space*/
;
j=i;
while (s[--j]==' ' && j>0) /*Go to the last non-space*/
; /*char before s*/

if (s[j]!=' ')
j++; /*Increment j so that s[j] is a space*/

if (j<i) /*If extra spaces have been found, remove*/
while (s) /*them by left shifting */
s[++j]=s[++i]; /*the characters on the right*/

i=j;
}
puts(s);

return 0;
}

The program works fine, but I have a feeling that I've made it
unnecessarily complicated.


Can anyone suggest ways on which I can improve upon the code? Is there
a better algorithm?


Much faster & efficient IMO (in most cases I would think) to
malloc a new string, copy the original one into it and then update the
original in place - no repeated shuffling.

strcpy(refCopy,refStr)
char *d=refStr; /*destination*/
char *s=refCopy; /*original string copy - source*/
while(*d++=(ch=*s++))
if(ch==' '){
while((ch=*s++)&&(ch==' ')); /*gobble up following spaces
if (!(*d++=ch)) /* store first non space */
break;
}

Not tested, but you will get the idea.


Thanks for the idea, Richard. I've implemented something similar:

#include <stdio.h>
#define MAX 80
int main()
{
char s[MAX];
int i, j;
fgets(s, MAX, stdin);
i=j=0;
while(s[i++]=s[j++])
{
if (s[i-1]==' ') /*If the last character copied was a space*/
{
while (s[j++]==' ') /*gobble up following spaces */
;
if ((s[i++]=s[j-1])=='\0')
break;
}
}
puts(s);
return 0;
}
Idiocy alert : you dont even need the copy thus saving fannying around
with mallocs etc. Just set s to be d. This is fine since s is always
the same or, after the first double space, ahead of the destination pointer.

Whoops.

Yeah, that was funny.
 
F

free4trample

Actually made the body of my lst post too complex, here is the bug
free, simpler version.

===================Start paste===============
#include<stdio.h>
#include<string.h>
#define MAX_LINE_LENGHTH 200
#define MAX_FN_LENGTH 20

int main(void){
char filein[MAX_FN_LENGTH], fileout[MAX_FN_LENGTH],
s1[MAX_LINE_LENGHTH], *s2;
FILE *ff1, *ff2;

printf("Enter input file: ");
scanf("%s",filein);
printf("\nEnter output file: ");
scanf("%s",fileout);
ff1=fopen(filein,"r");
ff2=fopen(fileout,"w");

while(!feof(ff1)){
fgets(s1,MAX_LINE_LENGHTH,ff1);
s2=strtok(s1," ");
fprintf(ff2,"%s",s2);
while((s2=strtok('\0'," "))!=NULL){
fprintf(ff2," %s",s2);
}
}

fclose(ff1);
fclose(ff2);
return 0;
}
=================End Paste====================

This one has no bugs either.
 
R

Richard Heathfield

(e-mail address removed) said:
This si as simple as it gets, i think...
Problem with this code is that it adds a SPACE character at the end of
a file.

====================Start paste=======================
#include<stdio.h>
#include<string.h>
#define MAX_LINE_LENGHTH 200
#define MAX_FN_LENGTH 20

int main(void){
char filein[MAX_FN_LENGTH], fileout[MAX_FN_LENGTH],
s1[MAX_LINE_LENGHTH], *s2;
FILE *ff1, *ff2;

printf("Enter input file: ");
scanf("%s",filein);

ThisIsWhatITypeInResponseToYourInputRequest. That's mischievous, but not
malicious. If you use "%s" with scanf, you open yourself up to malice as
well as mischief.

printf("\nEnter output file: ");
scanf("%s",fileout);

Same applies.
ff1=fopen(filein,"r");
ff2=fopen(fileout,"w");

What if these operations fail?
while(!feof(ff1)){
fgets(s1,MAX_LINE_LENGHTH,ff1);

This code will process the last line twice. Instead, use:

while(fgets(s1, MAX_LINE_LENGHTH, ff1) != NULL)
{

or better still:

while(fgets(s1, sizeof s1, ff1) != NULL)
{
 
F

free4trample

Can any one make it even shorter than this:


===================Start Paste===========================
#include<stdio.h>
#include<string.h>
#define MAX_LINE_LENGHTH 200

int main(int argc[], char *argv[]){
char s1[MAX_LINE_LENGHTH], *s2;
FILE *ff1, *ff2;

ff1=fopen(argv[1],"r");
ff2=fopen(argv[2],"w");

while(fgets(s1,MAX_LINE_LENGHTH,ff1)!=NULL){
s2=strtok(s1," ");
fprintf(ff2,"%s",s2);
while((s2=strtok('\0'," "))!=NULL) fprintf(ff2," %s",s2);
}

fclose(ff1);
fclose(ff2);
return 0;
}
=======================End Paste==========================
 
T

Thad Smith

Registered said:
Hi experts,
I'm trying to write a program that replaces two or more consecutive
blanks in a string by a single blank.

just as an alternative,

/*removes extra blanks from a string, replaces two or more consecutive
blanks in a string by a single space.*/
int sglspc(char *s){
int n;
char *p, *p2;

n = 0;
p = s;

while (*p){
if (*p == ' ' && *(p + 1) == *p){
n++;
p2 = p;

while (*p2){
*p2 = *(p2 + 1);
p2++;
}
} else
p++;
}

return n;
}

#include <stdio.h>
#include <string.h>
int main(void){
char s[] = " hello world ";
int n;

printf("%s, %d\n", s, strlen(s));
n = sglspc(s);
printf("%s, %d, (-%d)\n", s, strlen(s), n);

return 0;
}

int sglspc(char *s){
int n = 0;
char *d = s;
while (*d++ = *s)
while (*s++ == ' ' && *s == ' ') n++;
return n;
}

As part of a real program, it would be longer.
 
L

lovecreatesbea...

Thad said:
Registered said:
Hi experts,
I'm trying to write a program that replaces two or more consecutive
blanks in a string by a single blank.

just as an alternative,

/*removes extra blanks from a string, replaces two or more consecutive
blanks in a string by a single space.*/
int sglspc(char *s){
int n;
char *p, *p2;

n = 0;
p = s;

while (*p){
if (*p == ' ' && *(p + 1) == *p){
n++;
p2 = p;

while (*p2){
*p2 = *(p2 + 1);
p2++;
}
} else
p++;
}

return n;
}

#include <stdio.h>
#include <string.h>
int main(void){
char s[] = " hello world ";
int n;

printf("%s, %d\n", s, strlen(s));
n = sglspc(s);
printf("%s, %d, (-%d)\n", s, strlen(s), n);

return 0;
}

Your code is better than mine, thanks for sharing. I've learnt a lot
from your code.
int sglspc(char *s){
int n = 0;
char *d = s;

H&S5 says that initializations would be skipped. So I use explicit
assignments there. Do understand it correctly?
while (*d++ = *s)
while (*s++ == ' ' && *s == ' ') n++;

Excellent! It's clearer and more understandable and readable than the
one in my last post. At the very start, frankly, I don't understand it
- stupid me - but catch it finally.
return n;
}

As part of a real program, it would be longer.

Should it check in real program whether the parameter pointer s is null
or not inside this function body itself?
 
F

free4trample

This version does not need the string.h header file

================Start Paste===================

#include<stdio.h>
#define MAX_LINE_LENGHTH 200

int main(int argc[], char *argv[]){
char s1[MAX_LINE_LENGHTH], ch=' ';
FILE *ff1, *ff2;
int i1;

ff1=fopen(argv[1],"r");
ff2=fopen(argv[2],"w");

while(fgets(s1,MAX_LINE_LENGHTH,ff1)!=NULL){
i1=-1;
while(s1[(i1++)+1]!=NULL){
if(s1[i1]!=' ' || s1[i1]!=ch)
ch=fputc(s1[i1],ff2);
}
}
fclose(ff1);
fclose(ff2);
return 0;
}

====================End Paste========================
 
L

lovecreatesbea...

Thad Smith wrote:

H&S5 says that initializations would be skipped. So I use explicit
assignments there. Do understand it correctly?

Sorry, it is not complete.

I remember that H&S5 says for anto variables, their initializations
will be skipped. Do I understand it correctly?
 
T

Thad Smith

H&S5 says that initializations would be skipped. So I use explicit
assignments there. Do understand it correctly?

No, initializations of auto variables are performed on encountering the
declarations in the control flow. I don't have H&S to refer to. Maybe
they meant that an initialization of static variables would only occur
once, not each invocation.
Should it check in real program whether the parameter pointer s is null
or not inside this function body itself?

I wouldn't do that, but would instead clearly document the parameter
requirements and return value. I would also add more to make the
program a little easier to read and use my own brace rules:

while ((*d++ = *s) != '\0') {
while (*s++ == ' ' && *s == ' ') n++;
}
return n;
}

The explicit comparison with '\0' makes the intent clearer and
eliminates a warning from some compilers. The unneeded braces is my own
rule to use braces if the statement following a for, while, if, or else
is on a following line (otherwise I have forgotten that there is no
brace and added another indented line below the original -- oops!).
 

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

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top