Where did my values go??? 
Author Message
 Where did my values go???

Hi,

I am a beginning C programmer (just 2 weeks) and am having a simple
problem...I think.  The file i am working on should trim any whitespace
from the right and left side of an array of characters.  I just can't
seem to keep the values in the array after the getline() exits.  I have
pasted in the code for some help if anyone can offer it.

Thanks a lot,
Joe

PS
This is the first time i have posted on a newsgroup, so if i have broken
some etiquite, please let me know and I will remedy it.

 *  This program will remove any whitespace at the end and the beginning of
 *  a line.
 *
 */

#include <stdio.h>
#define MAX 1000

int rtrim(char s[]);
int ltrim(char s[]);
char s[MAX];

main()
{
int j;
while((j = getline(s, MAX)) > 0)
  {
rtrim(s);
  }
ltrim(s);

Quote:
}

int rtrim(char s[])
{
  int i;
  int j = getline(s , MAX);

  /*j-2 because the last two array values are null and \n*/

  for (i = j - 2; s[i] == ' ' || s[i] == '\t'; i--)
     {
       s[i] = '\0';
     }
  return 0;

Quote:
}

int ltrim(char s[])
{
 int i;
 for(i = 0; s[i] != '\0' ; i++)
   {
     if(s[i] == ' ' || s[i] == 't')
       s[i+1] = s[i];
   }
  return 0;

Quote:
}

/* This method will fill the array with each new line */
int getline (char s[], int lim)
{
  int c, i;
  static char s[MAX];
  for (i = 0; i<lim-1 && (c = getchar()) !=EOF && c != '\n'; ++i)
  {
    s[i] = c;
  }
     if (c == '\n')
       {
         s[i] = c;
         ++i;
       }
  s[i] = '\0';
  return i;
Quote:
}

--



Thu, 13 Mar 2003 10:47:40 GMT  
 Where did my values go???
See annotations.


Quote:
>Hi,

>I am a beginning C programmer (just 2 weeks) and am having a simple
>problem...I think.  The file i am working on should trim any whitespace
>from the right and left side of an array of characters.  I just can't
>seem to keep the values in the array after the getline() exits.  I have
>pasted in the code for some help if anyone can offer it.

>Thanks a lot,
>Joe

>PS
>This is the first time i have posted on a newsgroup, so if i have broken
>some etiquite, please let me know and I will remedy it.

> *  This program will remove any whitespace at the end and the beginning of
> *  a line.
> *
> */

>#include <stdio.h>
>#define MAX 1000

>int rtrim(char s[]);
>int ltrim(char s[]);
>char s[MAX];

>main()

main must return an int and should be defined as such.  The implied
int return is no longer allowed by the standard.  Since you don't want
parameters, you should specify void.  This yields a correct definition
of main as:
        int main(void)
Quote:
>{
>int j;
>while((j = getline(s, MAX)) > 0)

You have no prototype for getline.
Quote:
>  {
>rtrim(s);

PLEASE learn to indent consistently.
Quote:
>  }
>ltrim(s);

Is there some reason you rtrim all lines but only ltrim a line with no
characters?  I think you want ltrim inside the brace also.
How do you know if it worked?  You never output the result.
Quote:

>}

>int rtrim(char s[])
>{
>  int i;
>  int j = getline(s , MAX);

Why are you getting another line?  main already passed you an array
containing characters.
Quote:

>  /*j-2 because the last two array values are null and \n*/

'\n' will be in the array only under certain conditions.  It is
entirely possible for getline to not store a '\n' in s.

- Show quoted text -

Quote:

>  for (i = j - 2; s[i] == ' ' || s[i] == '\t'; i--)
>     {
>       s[i] = '\0';
>     }
>  return 0;
>}

>int ltrim(char s[])
>{
> int i;
> for(i = 0; s[i] != '\0' ; i++)
>   {
>     if(s[i] == ' ' || s[i] == 't')
>       s[i+1] = s[i];
>   }

Assume s contains blank, 'a', 'b', and '\0'.  When i=0, s[i] = ' '.
You then copy this blank to s[1], erasing the 'a'.  I think you meant
to write
        s[i] = s[i+1];
but this is still incorrect since s will now contain 'a', 'a', 'b',
and '\0'.  You will not find any more blanks and that is the value you
will leave in s.

Another problem with this loop is that it does not stop at the first
non blank. If there are blanks imbedded in the middle of your line,
you will process them even though you shouldn't.

Quote:
>  return 0;
>}

>/* This method will fill the array with each new line */
>int getline (char s[], int lim)
>{
>  int c, i;
>  static char s[MAX];

s is a parameter to this function; you cannot redefine it.
Quote:
>  for (i = 0; i<lim-1 && (c = getchar()) !=EOF && c != '\n'; ++i)
>  {
>    s[i] = c;
>  }
>     if (c == '\n')
>       {
>         s[i] = c;
>         ++i;
>       }
>  s[i] = '\0';
>  return i;
>}

You need to up the warning level on your compiler since that would
have told you of some of these problems.

<<Remove the del for email>>
--



Wed, 19 Mar 2003 03:00:00 GMT  
 Where did my values go???

Quote:

> main()

Nowadays, this should be written: int main(void)

Quote:
> {
> int j;
> while((j = getline(s, MAX)) > 0)
>   {
> rtrim(s);
>   }
> ltrim(s);

I suppose the ltrim call should be inside the loop.  Also,
consider adding puts(s) so that you see the result.

return 0;

(Does C99 make this automatic, like in C++?)

Quote:
> }

> int rtrim(char s[])
> {
>   int i;
>   int j = getline(s , MAX);

It would be good to add comments about the purpose of each
function.  Now your main() calls getline() and gives the buffer
to rtrim(), which calls getline() again.

Quote:

>   /*j-2 because the last two array values are null and \n*/

Your getline() doesn't store '\n' if the line is too long or if
the input stream ends without a '\n'.

(Off topic: Is it "a '\n'" or "an '\n'"?  I suppose that depends
on whether one pronounces "\" as "backslash" or "escape".)

Quote:

>   for (i = j - 2; s[i] == ' ' || s[i] == '\t'; i--)
>      {
>        s[i] = '\0';
>      }

If s[] contains only spaces, this loop decrements i past 0 and
can write outside the array.

You could use the library function isspace() if you also want to
trim characters like non-breaking spaces (assuming your system
supports such characters).  This would also take care of the
'\n'.

I might write the loop as:

   i = j;
   while (i > 0 && isspace(s[i-1]))
      --i;
   s[i] = '\0';

which finds the first space at the end of the string and replaces
only that with '\0'.

Quote:
>   return 0;

Why does the function return 0?  If this is some kind of
success/error code, you should write comments about that.  If the
returned value doesn't mean anything, change the function to
return void.

Quote:
> }

> int ltrim(char s[])
> {
>  int i;
>  for(i = 0; s[i] != '\0' ; i++)
>    {
>      if(s[i] == ' ' || s[i] == 't')

That should probably be '\t'.

Quote:
>        s[i+1] = s[i];

This copies the ' ' or '\t' over the next character which might
be the terminating '\0'.  And in the next iteration, s[i] is
again the ' ' or '\t' so the loop overwrites the entire string
and more.

Quote:
>    }

You should perhaps make the loop just find the first non-space
character, and after the loop memmove() the string from there to
the beginning of s[].  Don't use strcpy(), because that isn't
guaranteed to work with overlapping strings.

Quote:
>   return 0;
> }

Another way would be to make ltrim() return the address of the
first non-space character, instead of copying anything.  You'd
then have to change main() to use the string beginning at that
address.

Quote:

> /* This method will fill the array with each new line */

In C, it's called a function.

The comment should also say that lim includes the '\n' and '\0',
what the returned value means and what the function does if the
line doesn't fit.  (It stores lim-1 characters and '\0', and
leaves the rest of the line unread.)

Quote:
> int getline (char s[], int lim)
> {
>   int c, i;

It might be useful to change the types of lim, i and the returned
value to size_t, which can hold the size of any object.  It is an
unsigned type, which sometimes causes trouble, but this function
seems safe.

Quote:
>   static char s[MAX];

This causes the problem you mentioned: getline() stores the
characters in the local s[] and not in the parameter s[].

Quote:
>   for (i = 0; i<lim-1 && (c = getchar()) !=EOF && c != '\n'; ++i)
>   {
>     s[i] = c;
>   }
>      if (c == '\n')
>        {
>          s[i] = c;
>          ++i;
>        }

I'd write that as:

   for (i = 0; i < lim-1 && (c = getchar()) != EOF; )
   {
      s[i++] = c;
      if (c == '\n')
         break;
   }

Some people may object to break statements, but IMHO the above is
quite readable and makes it clear that c is initialized before it
is compared to '\n'.

Quote:
>   s[i] = '\0';
>   return i;
> }
> PS
> This is the first time i have posted on a newsgroup, so if i have broken
> some etiquite, please let me know and I will remedy it.

Your posting is just fine.  :-)
--



Wed, 19 Mar 2003 03:00:00 GMT  
 Where did my values go???

Quote:

> Hi,
> I am a beginning C programmer (just 2 weeks) and am having a simple
> problem...I think.  The file i am working on should trim any whitespace
> from the right and left side of an array of characters.  I just can't
> seem to keep the values in the array after the getline() exits.  I have
> pasted in the code for some help if anyone can offer it.
> Thanks a lot,
> Joe

[ SNIP - I haven't checked really this code. But I've got a strong suspicion
 that it contains at least a few bugs - like too many calls of getline(). ]

Quote:
> /* This method will fill the array with each new line */

Which begs the question: Which array?

Quote:
> int getline (char s[], int lim)
> {
>   int c, i;
>   static char s[MAX];

Just what is this array doing? You already have an array named 's'
as an argument, and that is where you want the result of the function
to end up. This one probably generates a warning from your compiler.
(you DO compile with all warnings enabled, do you ?) that this 's'
is hiding an 's' from an outer scope or something like that. That means
the argument isn't used.
BTW, why is the local 's' static? That doesn't fix anything.

Quote:
>   for (i = 0; i<lim-1 && (c = getchar()) !=EOF && c != '\n'; ++i)
>         s[i] = c;

[ SNIP ]

Well, the 's' you're writing to is function local, and can't be accessed
from outside getline().
--



Wed, 19 Mar 2003 03:00:00 GMT  
 Where did my values go???

[...]

Quote:
> char s[MAX];

[...]

Quote:
> /* This method will fill the array with each new line */
> int getline (char s[], int lim)
> {
>   int c, i;
>   static char s[MAX];

This is your problem. 'getline()' has its own, local variable 's'.
Get rid of this line, and your code should make some progress.

--

Even if all the snow were burnt, ashes would remain.
--



Wed, 19 Mar 2003 03:00:00 GMT  
 Where did my values go???

Quote:

> int getline (char s[], int lim)
> {
>   int c, i;
>   static char s[MAX];

You pass the function a parameter called s, and immediately shadow it
with a local array also called s. You then proceed to fill the second s,
but the calling function expects the first s to be filled. It isn't, and
the caller gets the same garbage back as it passed in.

Richard
--



Wed, 19 Mar 2003 03:00:00 GMT  
 Where did my values go???

Quote:

> Hi,

> I am a beginning C programmer (just 2 weeks) and am having a simple
> problem...I think.  The file i am working on should trim any whitespace
> from the right and left side of an array of characters.  I just can't
> seem to keep the values in the array after the getline() exits.  I have
> pasted in the code for some help if anyone can offer it.

> Thanks a lot,
> Joe

> PS
> This is the first time i have posted on a newsgroup, so if i have broken
> some etiquite, please let me know and I will remedy it.

/*

Quote:
>  *  This program will remove any whitespace at the end and the beginning of
>  *  a line.
>  *
>  */

> #include <stdio.h>
> #define MAX 1000

> int rtrim(char s[]);
> int ltrim(char s[]);
> char s[MAX];

int getline (char *, int);

Quote:

> main()

int main (void)

Quote:
> {
> int j;
> while((j = getline(s, MAX)) > 0)

/* Right, you get a line into 's' */

Quote:
>   {
> rtrim(s);

/* But your definition of rtrim() calls getline() again, overwriting
 * what's in 's' the first time.
 */

Quote:
>   }
> ltrim(s);

return 0;

Quote:
> }

> int rtrim(char s[])
> {
>   int i;
>   int j = getline(s , MAX);

/* Modify rtrim() to take 'j' as a parameter, rather than calling
 * getline() again -- because that's destroying whatever was in
 * 's' (or rather, it would, if getline worked).

- Show quoted text -

Quote:

>   /*j-2 because the last two array values are null and \n*/

>   for (i = j - 2; s[i] == ' ' || s[i] == '\t'; i--)
>      {
>        s[i] = '\0';
>      }
>   return 0;
> }

> int ltrim(char s[])
> {
>  int i;
>  for(i = 0; s[i] != '\0' ; i++)
>    {
>      if(s[i] == ' ' || s[i] == 't')
>        s[i+1] = s[i];
>    }
>   return 0;
> }

> /* This method will fill the array with each new line */
> int getline (char s[], int lim)
> {
>   int c, i;
>   static char s[MAX];

/* This declaration of 's' hides the parameter passed in,
 * therefore your text will be stored in the local array,
 * which will cease to exist at the end of this function.
 * Remove this declaration!
 */

Quote:
>   for (i = 0; i<lim-1 && (c = getchar()) !=EOF && c != '\n'; ++i)
>   {
>     s[i] = c;
>   }
>      if (c == '\n')
>        {
>          s[i] = c;
>          ++i;
>        }
>   s[i] = '\0';
>   return i;
> }
> --


--
Jonathan Headland               "function returning void" is oxymoronic
--
ans = comp.lang.c (msg); /* if msg is not about C, result undefined */
--
--



Wed, 19 Mar 2003 03:00:00 GMT  
 Where did my values go???

Quote:
> Hi,

> I am a beginning C programmer (just 2 weeks) and am having a simple
> problem...I think.  The file i am working on should trim any whitespace
> from the right and left side of an array of characters.  I just can't
> seem to keep the values in the array after the getline() exits.  I have
> pasted in the code for some help if anyone can offer it.

> Thanks a lot,
> Joe

> PS
> This is the first time i have posted on a newsgroup, so if i have broken
> some etiquite, please let me know and I will remedy it.

I haven't checked the behaviour of rtrim() or ltrim(), but here are some
comments:

Quote:
>  *  This program will remove any whitespace at the end and the beginning
of
>  *  a line.
>  *
>  */

> #include <stdio.h>
> #define MAX 1000

> int rtrim(char s[]);
> int ltrim(char s[]);
> char s[MAX];

Consider making this a "stack" variable of the main function. You're passing
it's value anyway...

Quote:

> main()

Use:
    int main(void)

Quote:
> {
> int j;
> while((j = getline(s, MAX)) > 0)
>   {
> rtrim(s);
>   }
> ltrim(s);

> }

> int rtrim(char s[])
> {
>   int i;
>   int j = getline(s , MAX);

Why are you calling getline() again? This way you'll probably read only
other every line.

Quote:

>   /*j-2 because the last two array values are null and \n*/

>   for (i = j - 2; s[i] == ' ' || s[i] == '\t'; i--)
>      {
>        s[i] = '\0';
>      }
>   return 0;
> }

> int ltrim(char s[])
> {
>  int i;
>  for(i = 0; s[i] != '\0' ; i++)
>    {
>      if(s[i] == ' ' || s[i] == 't')
>        s[i+1] = s[i];
>    }
>   return 0;
> }

> /* This method will fill the array with each new line */
> int getline (char s[], int lim)
> {
>   int c, i;
>   static char s[MAX];

Will this work? My guess is: lose the 'static char s[MAX]'. Probably it will
be in scope of the function, hiding the parameter. My other guess is that
the compiler will complain about it.

Quote:
>   for (i = 0; i<lim-1 && (c = getchar()) !=EOF && c != '\n'; ++i)
>   {
>     s[i] = c;
>   }
>      if (c == '\n')
>        {
>          s[i] = c;
>          ++i;
>        }
>   s[i] = '\0';
>   return i;
> }

You could "trim" the left spaces while reading the input. This saves you
some string shifting in ltrim().

There is this function: fgets() which will most decently do what you want in
getline(). It may be different (check man pages) on the '\n'.

Effectively, the program has no output, even when you use the comments. Try
printing the result somewhere.

Hope this helps,
    Pieter
--



Wed, 19 Mar 2003 03:00:00 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. How Should I go about doing this?

2. Doing something and still having the GUI go

3. Ok, how would i go about doing this?

4. how to go abt doing it?

5. why is lint going/gone?

6. Value, value, who's got the value?

7. Resetting PropertyGrid value to old value

8. addition long values to long double value ?

9. global value and extern value

10. How can I transform a int value to a char value

11. read WMF-header and convert DWORD value to integer value

12. l-value and r-value

 

 
Powered by phpBB® Forum Software