Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Remove extra blanks

Reply
Thread Tools

Remove extra blanks

 
 
Registered User
Guest
Posts: n/a
 
      10-15-2006
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[i]*/

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[i]) /*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?

 
Reply With Quote
 
 
 
 
CBFalconer
Guest
Posts: n/a
 
      10-15-2006
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[i]*/
>
> 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[i]) /*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;
}

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>


 
Reply With Quote
 
 
 
 
Richard
Guest
Posts: n/a
 
      10-15-2006
"Registered User" <(E-Mail Removed)> writes:

> 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[i]*/
>
> 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[i]) /*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.


--


--
 
Reply With Quote
 
Joe Wright
Guest
Posts: n/a
 
      10-15-2006
CBFalconer wrote:
> 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[i]*/
>>
>> 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[i]) /*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;
}

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
 
Reply With Quote
 
Richard
Guest
Posts: n/a
 
      10-15-2006
Joe Wright <(E-Mail Removed)> writes:

> CBFalconer wrote:
>> 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[i]*/
>>>
>>> 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[i]) /*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.

--
 
Reply With Quote
 
Registered User
Guest
Posts: n/a
 
      10-15-2006

Richard wrote:
> Joe Wright <(E-Mail Removed)> writes:
>
> > CBFalconer wrote:
> >> 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[i]*/
> >>>
> >>> 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[i]) /*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.

 
Reply With Quote
 
Andrew Poelstra
Guest
Posts: n/a
 
      10-15-2006
On Sun, 2006-10-15 at 04:22 -0700, Registered User wrote:
> 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[i]*/
>
> 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[i]) /*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.

--
Andrew Poelstra <http://www.wpsoftware.net/projects/>

 
Reply With Quote
 
lovecreatesbea...@gmail.com
Guest
Posts: n/a
 
      10-15-2006

Registered User wrote:
> 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[i]*/
>
> 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[i]) /*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)

$

 
Reply With Quote
 
Richard
Guest
Posts: n/a
 
      10-15-2006
Richard <(E-Mail Removed)> writes:

> "Registered User" <(E-Mail Removed)> writes:
>
>> 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[i]*/
>>
>> 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[i]) /*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.


--
 
Reply With Quote
 
jacob navia
Guest
Posts: n/a
 
      10-15-2006
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;
}
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Does return-by-value mean extra copies and extra overhead? mathieu C++ 3 09-04-2009 04:25 PM
log4j for webapp ..how to remove extra info getting printed harryos Java 3 12-15-2008 03:52 PM
How to remove extra lines in a XML file using perl pambouy2@hotmail.com Perl Misc 4 11-21-2005 12:48 AM
how do I remove extra data from serialize XML string of a DataSet IMS.Rushikesh@gmail.com ASP .Net Web Services 1 09-07-2005 04:20 PM
Remove extra CrLf's from textarea McKirahan Javascript 3 03-06-2004 10:28 PM



Advertisments