Strange Algorithm

I was following one of the exercises in the book:
http://users.powernet.co.uk/eton/kandr2/krx116.html

In the below example, the getline function returns the length of a line and fills up the line array with the characters of the line:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <stdio.h>

#define MAXLINE 1000 /* maximum input line size */

int getline(char line[], int maxline);
void copy(char to[], char from[]);

/* print longest input line */
int main(void)
{
  int len;               /* current line length */
  int max;               /* maximum length seen so far */
  char line[MAXLINE];    /* current input line */
  char longest[MAXLINE]; /* longest line saved here */

  max = 0;

  while((len = getline(line, MAXLINE)) > 0)
  {
    printf("%d: %s", len, line);

    if(len > max)
    {
      max = len;
      copy(longest, line);
    }
  }
  if(max > 0)
  {
    printf("Longest is %d characters:\n%s", max, longest);
  }
  printf("\n");
  return 0;
}

/* getline: read a line into s, return length */
int getline(char s[], int lim)
{
  int c, i, j;

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

/* copy: copy 'from' into 'to'; assume 'to' is big enough */
void copy(char to[], char from[])
{
  int i;

  i = 0;
  while((to[i] = from[i]) != '\0')
  {
    ++i;
  }
}


I don't understand why they are using this line right here: s[j++] = c;. What that does is assign the character to index 1 of the line array, rather than index 0, which is the beginning. It makes no sense. Why would they leave index 0 with a garbage value? Secondly, I see no point of the j variable as well. It would make more sense if it was: s[i] = c. Am I missing something?
johnmerlino wrote:
What that does is assign the character to index 1 of the line array, rather than index 0, which is the beginning.

No, it's not. It's assigning c to s[j] and then incrementing j.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>

int main( int argc, char* argv[] )
{
    int my_ints[5];
    int j = 0;

    while( j < 5 )
        my_ints[j++] = 50;

    for( j = 0; j < 5; ++j )
        std::cout << "Value at " << j << ": " << my_ints[j] << std::endl;

    return 0;
}

Notice how all elements of the array have been assigned 50, including element 0.

johnmerlino wrote:
Secondly, I see no point of the j variable as well. It would make more sense if it was: s[i] = c. Am I missing something?

No, because they're incremented at different rates. The i counter is used to keep track of the length of the string. The j variable, at the end of the processing, stores the point where the null terminator needs to go in the string.

However, you could do this without j.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* getline: read a line into s, return length */
int getline(char s[], int lim)
{
  int c, i;

  for(i = 0 ; (c = getchar())!=EOF && c != '\n'; ++i)
  {
    if(i < lim - 1)
    {
      s[i] = c;
    }
  }
  if(c == '\n')
  {
    if(i <= lim - 1)
    {
      s[i] = c;
    }
    ++i;
  }
  s[i-1] = '\0';
  return i;
}
Last edited on
Topic archived. No new replies allowed.