Something wrong in my program

  • Thread starter Dominique =?ISO-8859-1?Q?L=E9ger?=
  • Start date
D

Dominique =?ISO-8859-1?Q?L=E9ger?=

Hello guys,

I'm kinda new to C, and I'm having a hard time with strings. What I'm trying
to do is a simple function that trims spaces & tabs at the beginning of a
given string. For example, I want this: " Hello World" to become this:
"Hello World". At first glance, my function seems to work, but returns some
strange values...

Here's my code (please pardon the mess):

#include <stdio.h>
#include <string.h>

int main(void){
char *trimbegin(char *text);
char *str = " Hello World!";
char *result = trimbegin(str);
printf("What the function returns: \"%s\"\n", result);
return 0;
}

char *trimbegin(char *text){
int i = 0, j = 0, ok = 0;
int size = strlen(text);
char buffer[size + 1];
char *ptr;

printf("Original text is: \"%s\"\n", text);
printf("That's %d characters long...\n", size);
printf("Now, our text buffer can contain %d characters\n", size +
1);
for (i = 0; i <= size; i++){
if (ok == 1){
buffer[j] = text;
j++;
}
else if (isspace(text) == 0 && ok == 0){
buffer[j] = text;
j++;
ok = 1;
}
}
printf("What the result is supposed to be: \"%s\"\n", buffer);
ptr = buffer;
return ptr;
}

And here's the output:

[dom@localhost C]$ ./a.out
Original text is: " Hello World!"
That's 14 characters long...
Now, our text buffer can contain 15 characters
What the result is supposed to be: "Hello World!"
What the function returns: "Hello World! @8@$÷ÿ¿¸öÿ¿PS@ý@Èöÿ¿"


Why does it return "Hello World! @8@$÷ÿ¿¸öÿ¿PS@ý@Èöÿ¿" and not "Hello
World!"?

Thanks for all your help!

-Dom
 
L

lallous

Dominique Léger said:
Hello guys,

I'm kinda new to C, and I'm having a hard time with strings. What I'm trying
to do is a simple function that trims spaces & tabs at the beginning of a
given string. For example, I want this: " Hello World" to become this:
"Hello World". At first glance, my function seems to work, but returns some
strange values...

Here's my code (please pardon the mess):

#include <stdio.h>
#include <string.h>

int main(void){
char *trimbegin(char *text);
char *str = " Hello World!";
char *result = trimbegin(str);
printf("What the function returns: \"%s\"\n", result);
return 0;
}

char *trimbegin(char *text){
int i = 0, j = 0, ok = 0;
int size = strlen(text);
char buffer[size + 1];
char *ptr;

printf("Original text is: \"%s\"\n", text);
printf("That's %d characters long...\n", size);
printf("Now, our text buffer can contain %d characters\n", size +
1);
for (i = 0; i <= size; i++){
if (ok == 1){
buffer[j] = text;
j++;
}
else if (isspace(text) == 0 && ok == 0){
buffer[j] = text;
j++;
ok = 1;
}
}
printf("What the result is supposed to be: \"%s\"\n", buffer);
ptr = buffer;
return ptr;
}

And here's the output:

[dom@localhost C]$ ./a.out
Original text is: " Hello World!"
That's 14 characters long...
Now, our text buffer can contain 15 characters
What the result is supposed to be: "Hello World!"
What the function returns: "Hello World! @8@$÷ÿ¿¸öÿ¿PS@ý@Èöÿ¿"


Why does it return "Hello World! @8@$÷ÿ¿¸öÿ¿PS@ý@Èöÿ¿" and not "Hello
World!"?

Thanks for all your help!

-Dom

Hello, guess you forgot to add a zero terminator to the string.

From the code, it would be something like: buffer[j] = 0 just right before
the printf() statement.
int size = strlen(text);
char buffer[size + 1];
I wonder how is this accepted by a C compiler?
 
C

Christopher Benson-Manica

Dominique Léger said:
char *trimbegin(char *text){
char buffer[size + 1];
char *ptr;
/* intervening code trimmed */
ptr = buffer;
return ptr;
^^^^^^^^^^ returns the address of buffer! (clc nitpicks
on that statement welcome!)

Surprisingly (at least to you ;)), this is all the code you need to
see what's going wrong. You are returning the address of an automatic
variable, and when trimbegin returns, the memory that was reserved for
buffer (and that ptr pointed to, and that you returned a pointer to)
is freed. Thus, that memory is no longer guaranteed to be good for
anything, and you should not use it. If you did something like

ptr=malloc( strlen(buffer)+1 ); /* sizeof( char ) guaranteed to be 1 */
strcpy( ptr, buffer );
return ptr;

you'd be fine.
 
J

Joona I Palaste

Christopher Benson-Manica said:
Dominique Léger said:
char *trimbegin(char *text){
char buffer[size + 1];
char *ptr;
/* intervening code trimmed */
ptr = buffer;
return ptr;
^^^^^^^^^^ returns the address of buffer! (clc nitpicks
on that statement welcome!)

Actually it returns the address of a char, which corresponds to the
exact same machine-level address as the address of buffer. The only
difference between them is the type.
 
C

Christopher Benson-Manica

Christopher Benson-Manica said:
If you did something like
(blah)
you'd be fine.

Well, that and listened (probably) to a previous poster who wondered why you
were able to compile

char buffer[size+1]; /* dynamic size arrays are C99, yes? */
 
I

Irrwahn Grausewitz

Dominique Léger said:
Hello guys,

I'm kinda new to C, and I'm having a hard time with strings. What I'm trying
to do is a simple function that trims spaces & tabs at the beginning of a
given string. For example, I want this: " Hello World" to become this:
"Hello World". At first glance, my function seems to work, but returns some
strange values...

Here's my code (please pardon the mess):

#include <stdio.h>
#include <string.h>

#include said:
int main(void){
char *trimbegin(char *text);
Function prototypes shouldn't be buried in function definitions,
IMO. Move the prototype outside main, or define trimbegin before
main.
char *str = " Hello World!";
char *result = trimbegin(str);
printf("What the function returns: \"%s\"\n", result);
return 0;
}

char *trimbegin(char *text){
int i = 0, j = 0, ok = 0;
int size = strlen(text);
char buffer[size + 1];
char *ptr;

printf("Original text is: \"%s\"\n", text);
printf("That's %d characters long...\n", size);
printf("Now, our text buffer can contain %d characters\n", size +
1);
for (i = 0; i <= size; i++){
if (ok == 1){
buffer[j] = text;
j++;
}
else if (isspace(text) == 0 && ok == 0){
buffer[j] = text;
j++;
ok = 1;
}
}


That's a very complicated way to do the job at hand.
printf("What the result is supposed to be: \"%s\"\n", buffer);
ptr = buffer;

Obfuscation is not a cure for undefined behaviour... ;-)
return ptr;

... which you invoke here by returning an invalid address, since
buffer will be gone when control reaches end of function.
Either
- qualify buffer static (rendering the function non-reentrant
and making C99 VLAs impossible to use), or
- provide a second parameter and let the caller provide the
buffer, or
- dynamically allocate memory for buffer in the function and
document that the caller has to free the memory if it's no
longer needed, or
- return only a pointer to the first non-whitespace character
in the original string,
whatever fits your needs best.

The last one is particularly easy to implement:

char *skipspace( char *s )
{
while ( isspace( *s ) )
s++;
return s;
}
}

And here's the output:

[dom@localhost C]$ ./a.out
Original text is: " Hello World!"
That's 14 characters long...
Now, our text buffer can contain 15 characters
What the result is supposed to be: "Hello World!"
What the function returns: "Hello World! @8@$÷ÿ¿¸öÿ¿PS@ý@Èöÿ¿"


Why does it return "Hello World! @8@$÷ÿ¿¸öÿ¿PS@ý@Èöÿ¿" and not "Hello
World!"?

You were lucky, because you invoked undefined behaviour, didn't
get what you expected (indicating that something's wrong) and
nothing really serious happened.

HTH

Regards
 
B

Bruno Desthuilliers

Dominique said:
Hello guys,

I'm kinda new to C, and I'm having a hard time with strings. What I'm trying
to do is a simple function that trims spaces & tabs at the beginning of a
given string. For example, I want this: " Hello World" to become this:
"Hello World". At first glance, my function seems to work, but returns some
strange values...

Here's my code (please pardon the mess):

#include <stdio.h>
#include <string.h>

int main(void){
char *trimbegin(char *text);

Move the function definition above the main(), and you won't have to
declare its prototype here.
char *str = " Hello World!";
char *result = trimbegin(str);
printf("What the function returns: \"%s\"\n", result);
return 0;
}

char *trimbegin(char *text){
int i = 0, j = 0, ok = 0;
int size = strlen(text);
should be a size_t, not an int.
char buffer[size + 1];
gcc -Wall -ansi -pedantic :
warning: ISO C89 forbids variable-size array `buffer'

char *ptr;

printf("Original text is: \"%s\"\n", text);
printf("That's %d characters long...\n", size);
printf("Now, our text buffer can contain %d characters\n", size +
1);
for (i = 0; i <= size; i++){
if (ok == 1){
buffer[j] = text;
j++;
}
else if (isspace(text) == 0 && ok == 0){

gcc -Wall -ansi -pedantic :
warning: implicit declaration of function `isspace'
buffer[j] = text;
j++;
ok = 1;
}
}


Are you sure your algorithm is ok and as simple as it could be ?
printf("What the result is supposed to be: \"%s\"\n", buffer);
ptr = buffer;
return ptr;

Which can be shortened to :
return &buffer[0];
and further to :
return buffer;

in which case you've got an additionnal, and very annoying warning :

gcc -Wall -ansi -pedantic :
warning: function returns address of local variable

You understand that, even if the value returned is an effective memory
address, what becomes of the memory block starting at this address is no
more under your control as soon as the function returns ? This memory
may be reclaimed and reused by the system at any time, so trying to read
at this at address may have any unpredictable result - not talking about
*writing* at this address.
And here's the output:

[dom@localhost C]$ ./a.out
Original text is: " Hello World!"
That's 14 characters long...
Now, our text buffer can contain 15 characters
What the result is supposed to be: "Hello World!"
What the function returns: "Hello World! @8@$÷ÿ¿¸öÿ¿PS@ý@Èöÿ¿"


Why does it return "Hello World! @8@$÷ÿ¿¸öÿ¿PS@ý@Èöÿ¿" and not "Hello
World!"?

First you forgot to copy the terminating '\0' to buffer, so buffer is
char array, but not a string. In C, a string is a char array *terminated
by the char '\0'*. Note that this character is *not* counted by
strlen(), since it's not part of the string, but merely a 'sentinel'
indicating where the string ends (the 'effective' string may be shorter
than the memory block it is contained in).

Then, you return the address of a local automatic variable, which
invokes UB (Undefined Behavior) as soon as you read or write at this
address. Anything can happen, even that it *seems* to work correctly.

Solutions are :
- either dynamically allocate memory for buffer in trimbegin(), or
declare buffer outside trimbegin() and pass its address to trimbegin
(for now you'd better try the second solution)
- make sure that buffer terminates with a '\0' (the simplest way to do
it being to copy the terminating '\0' of the source string)
- eventually rewrite your algorithm to make it simpler

tip 1 : you dont need any test in the for loop body nor the ok flag
tip 2 : the for loop syntax is :
for (<initialisation>;<test>;<on_each_iteration>)
{
<body>
}
where any of <initialisation>, <test>, <on_each_iteration>, and
<body> can be empty.


Feel free to post amended code for review !-)

HTH
Bruno
 
C

Christopher Benson-Manica

Régis Troadec said:
int main()
{
char * str = " \tHello World";
char * trimmed;
printf("Original :\n%s\n",str);
trimmed = trim(str);
printf("Trimmed :\n%s\n",trimmed);
/* What will happen if trim fails (returns NULL)? Of course,
it never does so at the moment, but if it were coded
correctly it might... */
free(trimmed);
}
char* trim(char* s)
{
char * res;
int cnt = 0;
int cnt2 = 0;
while (isspace(s[cnt]) != 0)
cnt++;
res = (char*)malloc(sizeof(char)*(strlen(s)-cnt+1));
/* There are numerous reasons why casting the return value of
malloc() is inadvisable, although I will let others
enumerate them */
/* And of course, what if malloc() fails? */
while (s[cnt] != '\0')
res[cnt2++] = s[cnt++];
res[cnt2] = '\0';
return &res[0];
/* res===&res[0], so why obfuscate? */

I don't claim that all is well otherwise, but those are what my
untrained eyes see.
 
R

Régis Troadec

Hi,

Dominique Léger said:
Hello guys,

I'm kinda new to C, and I'm having a hard time with strings. What I'm trying
to do is a simple function that trims spaces & tabs at the beginning of a
given string. For example, I want this: " Hello World" to become this:
"Hello World". At first glance, my function seems to work, but returns some
strange values...

Here's my code (please pardon the mess):

#include <stdio.h>
#include <string.h>

#include said:
int main(void){
char *trimbegin(char *text);
char *str = " Hello World!";
char *result = trimbegin(str);
printf("What the function returns: \"%s\"\n", result);
return 0;
}

char *trimbegin(char *text){
int i = 0, j = 0, ok = 0;
int size = strlen(text);
char buffer[size + 1];

VLA in C99 only
char *ptr;

printf("Original text is: \"%s\"\n", text);
printf("That's %d characters long...\n", size);
printf("Now, our text buffer can contain %d characters\n", size +
1);
for (i = 0; i <= size; i++){
if (ok == 1){
buffer[j] = text;
j++;
}
else if (isspace(text) == 0 && ok == 0){
buffer[j] = text;
j++;
ok = 1;
}
}


I'm not sure about your algorithm, since ok is initialized to 0 and that
isspace() returns a non-zero value if it is a white-space character.
printf("What the result is supposed to be: \"%s\"\n", buffer);
ptr = buffer;
return ptr;
}

And here's the output:

[dom@localhost C]$ ./a.out
Original text is: " Hello World!"
That's 14 characters long...
Now, our text buffer can contain 15 characters
What the result is supposed to be: "Hello World!"
What the function returns: "Hello World! @8@$÷ÿ¿¸öÿ¿PS@ý@Èöÿ¿"


Why does it return "Hello World! @8@$÷ÿ¿¸öÿ¿PS@ý@Èöÿ¿" and not "Hello
World!"?
Thanks for all your help!

-Dom

I suggest you my example :

#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char* trim(char* s);

int main()
{
char * str = " \tHello World";
char * trimmed;
printf("Original :\n%s\n",str);
trimmed = trim(str);
printf("Trimmed :\n%s\n",trimmed);
free(trimmed);
}

char* trim(char* s)
{
char * res;
int cnt = 0;
int cnt2 = 0;

while (isspace(s[cnt]) != 0)
cnt++;

res = (char*)malloc(sizeof(char)*(strlen(s)-cnt+1));

while (s[cnt] != '\0')
res[cnt2++] = s[cnt++];

res[cnt2] = '\0';

return &res[0];
}

Best regards. régis
 
B

Bruno Desthuilliers

Régis Troadec said:
Hi,

(snip OP code)

I suggest you my example :

I suggest the small corrections below...
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char* trim(char* s);

int main()
int main(void) or int main(int argc, char **argv)
{
char * str = " \tHello World";
char * trimmed;
printf("Original :\n%s\n",str);
trimmed = trim(str);
printf("Trimmed :\n%s\n",trimmed);
free(trimmed);
}

char* trim(char* s)
{
char * res;
int cnt = 0;
int cnt2 = 0;

while (isspace(s[cnt]) != 0)
cnt++;

res = (char*)malloc(sizeof(char)*(strlen(s)-cnt+1));
res = malloc(strlen(s) - cnt + 1);
if (res != NULL) /* malloc may fail */
{
while (s[cnt] != '\0')
res[cnt2++] = s[cnt++];

res[cnt2] = '\0';
}
else {
/* whatever */
}
return &res[0]; return res;
}

HTH
Bruno
 
I

Irrwahn Grausewitz

lallous said:
"Dominique Léger" <[email protected]> wrote:
Hello, guess you forgot to add a zero terminator to the string.

This was my first thought too, but the OP apparently /did/ copy
the terminating null character. *But* the OP invoked UB by
returning the address to automatic storage, and that's why...
[...] buffer[j] = 0 just right before the printf() statement.

.... won't help.
int size = strlen(text);
char buffer[size + 1];
I wonder how is this accepted by a C compiler?

C99 VLA.

Regards
 
I

Irrwahn Grausewitz

Bruno Desthuilliers said:
Dominique Léger wrote:
First you forgot to copy the terminating '\0' to buffer, so buffer is
char array, but not a string.
<snip>

Even if it were the case, it would not explain the differences
between the two lines of output, re-quoted above.

Regards
 
T

those who know me have no need of my name

in comp.lang.c i read:
char buffer[size+1]; /* dynamic size arrays are C99, yes? */

yes, though it is called a variable length array.
 
D

David Resnick

Dominique Léger said:
Hello guys,

I'm kinda new to C, and I'm having a hard time with strings. What I'm trying
to do is a simple function that trims spaces & tabs at the beginning of a
given string. For example, I want this: " Hello World" to become this:
"Hello World". At first glance, my function seems to work, but returns some
strange values...

General comment: Consider turning on some more warnings on your
compiler. I see the following with
gcc -pedantic -Wall -W -std=c89 -o foo foo.c
foo.c:15: warning: ISO C89 forbids variable-size array `buffer'
foo.c:27: warning: implicit declaration of function `isspace'
The first may not bother you, the second shows failure to include
a needed header...
Here's my code (please pardon the mess):

#include <stdio.h>
#include <string.h>

#include said:
int main(void){

It is more usual to put your function declarations at file scope rather
than inside a function. And you might consider declaring the function
to be "static", the proper course to take for functions that are not
being used outside the current source file.
char *trimbegin(char *text);

You want const char *str here, to indicate this must not
be modified. This lets the compiler help you out by
pointing out any attempt to change this.
char *str = " Hello World!";
char *result = trimbegin(str);
printf("What the function returns: \"%s\"\n", result);
return 0;
}

You want const char *text as the argument, to indicate it is
not to be modified.
char *trimbegin(char *text){
int i = 0, j = 0, ok = 0;
int size = strlen(text);

The array size below is not a constant expression. That is OK in
C99 and as a compiler extension sometimes (it obviously works on
your compiler). Just FYI, it doesn't work on strict C89 compilers.
char buffer[size + 1];
char *ptr;

printf("Original text is: \"%s\"\n", text);
printf("That's %d characters long...\n", size);
printf("Now, our text buffer can contain %d characters\n", size +
1);

What is below seems to me to work just fine. But if you want to
write it a different and slightly simpler way, consider using a
loop to advance a pointer past the whitespace and then use a
strcpy to copy the rest.
for (i = 0; i <= size; i++){
if (ok == 1){
buffer[j] = text;
j++;
}
else if (isspace(text) == 0 && ok == 0){
buffer[j] = text;
j++;
ok = 1;
}
}

printf("What the result is supposed to be: \"%s\"\n", buffer);
ptr = buffer;


You are returning a pointer to "automatic" storage. This is a big
no-no. I believe (no standard handy) that this causes "undefined
behavior". What happens to the memory once you leave the scope at
which the storage is allocated, you don't know what is going to
happen to it. Thankfully, in your case, something bad DOES happen
so you know there is a problem. You either need to declare the
buffer array "static" (often a bad idea in larger programs, fine
here), or allocate some memory dynamically using malloc and free
it later.
return ptr;
}

And here's the output:

[dom@localhost C]$ ./a.out
Original text is: " Hello World!"
That's 14 characters long...
Now, our text buffer can contain 15 characters
What the result is supposed to be: "Hello World!"
What the function returns: "Hello World! @8@$÷ÿ¿¸öÿ¿PS@ý@Èöÿ¿"


Why does it return "Hello World! @8@$÷ÿ¿¸öÿ¿PS@ý@Èöÿ¿" and not "Hello
World!"?

Thanks for all your help!

-Dom
 
C

CBFalconer

Irrwahn said:
<snip>

Even if it were the case, it would not explain the differences
between the two lines of output, re-quoted above.

With all this foofaraw, nobody seems to point out that all trim
requires (for leading blanks) is:

const char *trim(const char *s)
{
while ((' ' == *s) || ('\t' == *s)) s++;
return s;
}
 
T

those who know me have no need of my name

in comp.lang.c i read:
With all this foofaraw, nobody seems to point out that all trim
requires (for leading blanks) is:

const char *trim(const char *s)
{
while ((' ' == *s) || ('\t' == *s)) s++;

isspace() may be better to use, as it is locale sensitive. then again some
may dislike that carriage control, line termination, and vertical white-
space are also included.
 
A

August Derleth

Régis Troadec said:
Hi,

Hello guys,

I'm kinda new to C, and I'm having a hard time with strings. What I'm
trying

to do is a simple function that trims spaces & tabs at the beginning of a
given string. For example, I want this: " Hello World" to become this:
"Hello World". At first glance, my function seems to work, but returns
some

strange values...

Here's my code (please pardon the mess):

#include <stdio.h>
#include <string.h>


int main(void){
char *trimbegin(char *text);
char *str = " Hello World!";
char *result = trimbegin(str);
printf("What the function returns: \"%s\"\n", result);
return 0;
}

char *trimbegin(char *text){
int i = 0, j = 0, ok = 0;
int size = strlen(text);
char buffer[size + 1];


VLA in C99 only

char *ptr;

printf("Original text is: \"%s\"\n", text);
printf("That's %d characters long...\n", size);
printf("Now, our text buffer can contain %d characters\n", size +
1);
for (i = 0; i <= size; i++){
if (ok == 1){
buffer[j] = text;
j++;
}
else if (isspace(text) == 0 && ok == 0){
buffer[j] = text;
j++;
ok = 1;
}
}



I'm not sure about your algorithm, since ok is initialized to 0 and that
isspace() returns a non-zero value if it is a white-space character.

printf("What the result is supposed to be: \"%s\"\n", buffer);
ptr = buffer;
return ptr;
}

And here's the output:

[dom@localhost C]$ ./a.out
Original text is: " Hello World!"
That's 14 characters long...
Now, our text buffer can contain 15 characters
What the result is supposed to be: "Hello World!"
What the function returns: "Hello World! @8@$÷ÿ¿¸öÿ¿PS@ý@Èöÿ¿"


Why does it return "Hello World! @8@$÷ÿ¿¸öÿ¿PS@ý@Èöÿ¿" and not "Hello
World!"?
Thanks for all your help!

-Dom


I suggest you my example :

#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char* trim(char* s);

int main()
{
char * str = " \tHello World";
char * trimmed;
printf("Original :\n%s\n",str);
trimmed = trim(str);
printf("Trimmed :\n%s\n",trimmed);
free(trimmed);

exit(EXIT_SUCCESS); /* 0 is fine, too */
/* or you could have return 0; just as well */
}

char* trim(char* s)
{
char * res;
int cnt = 0;
int cnt2 = 0;

while (isspace(s[cnt]) != 0)
cnt++;

res = (char*)malloc(sizeof(char)*(strlen(s)-cnt+1));
Not testing the return value of malloc() is VERY bad, because if
malloc() returns NULL you will attempt to access memory you don't own.
Which is a source of undefined behavior. Which means your program, OS,
and hardware can literally do /anything/ after that point.

It is important enough that even trivial code should test for a failure,
and some coders (myself included) have created a version of malloc that
will quit the program with an error message instead of returning NULL.
(That can be deeply stupid in some cases, which is why I only use it in
the cases where it makes sense.)

Casting the retval of malloc() is bad:
1. Can hide a failure to #include <stdlib.h> because if a prototype is
not in scope, malloc() implicitly returns an int. This can be dangerous
on some machines.
2. Makes code harder to change later, when you decide to make malloc()
allocate something besides a buffer of char.
3. Demonstrates a lack of knowledge about how a pointer to void works.
4. Introduces unneeded visual clutter.

sizeof(char) is unneeded, as sizeof(char) == 1 by definition.
while (s[cnt] != '\0')
res[cnt2++] = s[cnt++];

res[cnt2] = '\0';

return &res[0];

Why not just return res; ?
 
A

August Derleth

those said:
in comp.lang.c i read:

char buffer[size+1]; /* dynamic size arrays are C99, yes? */


yes, though it is called a variable length array.

What happens if you try to use a VLA to allocate more memory than your
OS will let your program have?
 
B

Bruno Desthuilliers

Irrwahn said:
<snip>

Even if it were the case, it would not explain the differences
between the two lines of output, re-quoted above.

Regards

That was the second point, that you may have noticed if you had read
further !-)

Regards too
 
B

Bruno Desthuilliers

CBFalconer wrote:
(snip)
With all this foofaraw, nobody seems to point out that all trim
requires (for leading blanks) is:

const char *trim(const char *s)
{
while ((' ' == *s) || ('\t' == *s)) s++;
return s;
}

Some did notice, but tried to lead the OP to discover this by himself
instead of giving him the solution.
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top