Truncate leading and trailing spaces

showbix
showbix used Ask the Experts™
on
1. Is there any functions in C that can truncate leading
and trailing spaces.

2. How do I concatenate in front of the string?
e.g

add "/dev/" to string abc
abc = "tty2a1"

final output should be like this, abc="/dev/tty2a1"
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:

1. There are no any functions for truncating spaces.

2. To concatenate string at front....
concatenate 'abc' to "/dev/"

main()
{

   char *str1="/dev/";
   char *abc = "tty2a1";
   char *ttypath;

   ttypath = (char *) malloc((strlen(str1) + strlen(abc) + 1) *sizeof(char));
   strcpy(ttypath, str1);
   strcat(ttypath, abc);

}


Hope this is what you expecting.

-Rohan
CEO/Programmer
Commented:
I'm a bit puzzling about the suggested code
first the prototyp is
int main(void)

one should not cast the return value from malloc and
sizeof(char) == 1 (always)

Than why use strcpy and strcat? Two times strcat should to the work.

Rohan has explained correctly that no standard function for
trimming whitespace is available. You might check out one of the existing implementations or write one yourself.

Here's a suggestion without error handling
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>




char * trim_whitespace (char * str){
     char *whitespace = " \t\v\r\n";
     size_t start = strspn(str, whitespace);
     size_t end = start + 1;
     size_t needed_size = 0;
     char * result = NULL;
     while (!isspace(str[end])){
          ++end;
     }
     needed_size = end - start;
     result = malloc(needed_size+1);
     strncpy (result, &str[start], needed_size);
        return result;
}



int main (void){
     char* some_str = "\t  withblanks   \t";
     char *result = trim_whitespace(some_str);
     printf("result = %s\n", result);
     free(result);
     return 0;
}

Error handling etc is left to the original poster

Regards
Friedrich
int main(void) or just main(void)
doesn't make a difference i think...since by default the return type is int

and yes one can safely cast the value of malloc in fact malloc returns a void * pointer which can be always safely explicitly casted to any type...


size of char is not always 1 i think...it is machine dependent...

Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Commented:
Regarding strcpy and then strcat...
 malloc function doesn't initializes the memory which it allocates. Hence, you are not sure about the contents of 'ttypath'. To initialize it, strcpy is used.
  If you use 'calloc' instead of malloc, two strcat would work.
  Its like you initialize a variable, before using its value so that you get expected result.


In above suggested  trim_whitespace function while loop should also test for end of string (\0 char). isspace does not check for end of string. The while loop should look like

  while (str[end] != '\0' && !isspace(str[end])){
         ++end;
    }

-Rohan
fridomCEO/Programmer

Commented:
Well too crcytpsis it makes a difference the main() is depracated and therfor should be avoided.

And no one should not cast a pointer while calling malloc in C, it always perfeclt legal to assign to and from a void*. Casing malloc could hide the fact that you missed the apppropriate header.

And no sizeof(char) is alway == 1
See ISO Standard C99 6.5.3.4 sentence 3 There you'll find
When applied to an operand that has type char, unsigned char or signed char ... the result is 1

To Rohan I told that I did not care about error handling and you even missed that something is missing adding a trailing
'\0' which is necessary because the string to be trimmed does not end at the next space and there is definitly no '\0' there.

So here a somewhat corrected version (without error checking)
char * trim_whitespace (char * str){
     char *whitespace = " \t\v\r\n";
     size_t start = 0;
     size_t end = 0;
     size_t needed_size = 0;
     char * result = NULL;

     start = strspn(str, whitespace);
     end = strcspn(&str[start], whitespace) + start;
     needed_size = end - start;
     result = malloc(needed_size+1);
     strncpy (result, &str[start], needed_size);
     result[needed_size] = '\0';
        return result;
}

This is IMHO even more elegant..

Regards
Friedrich
hey fridom you better check this link...

casting is very essential in case of malloc() ...
http://www.cs.columbia.edu/~novik/cs3133/notes/lect03.html

Commented:
The void * value returned by malloc is always suitably aligned for an object of any type. The cast is not necessary. The lecture notes are wrong if they are refering to ANSI or ISO C.

Reference H&S 4th ed, sect. 6.1.3 and 16.1
Refer also to Steve Summit's C FAQ http://www.eskimo.com/~scs/C-faq/q7.7.html
fridomCEO/Programmer

Commented:
Casting is wrong usually and especially with mallocs, calloc etc.

Regards
Friedrich
hmm... i didn't know about that...
actually guys even TURBO C recommends casting in its documentation...i have done most of c programming on turbo c so i do have a good reason to believe that casting is essential in C...well and i have used casting and malloc() together in many of the programs that i have developed in TURBO C you can check them on :

http://siddhesh.s5.com/download.htm

they run without errors...

anyways that's the reason i think we are here on EE to increase our knowledge and learn from our mistakes right!!!!!!!!!

cryptosid
In fact guys this is gr8 2 years of myth of mine has been removed i found this...
http://www.purdue.edu/PUCC/Short-Courses/c.files/p_01550.html

thank you fridom,ewest for removing my illusions
fridomCEO/Programmer

Commented:
Well I do not know what ewest means. And the examples in you link are one of the rare cases where casting may be needed. So is the usage for  generic sort. But you always can use a local variable of the appropriate type.

e.g (artificial)
int some_fun (void* generic_par){
// now you can't just do
// generic[10} = xxx
but
char * some_var = generic_par;

return some_var[10];

The generic pointer is very very useful and at least as dangerous...., A usage of it can be found e.g in the GTK Toolkit where it'is used to "simulate" OO in C.

I can't remember the last time I heard of Turbo C. I had a C on my Atari which was named that way....

Regards
Friedrich

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial