Question

I'm brand new to C and am trying to learn how to take a string and print it using a function. I see examples everywhere using while(ch = getchar(), ch >= 0), but as soon as I put it into a function (instead of main()), it ceases to work. Right now, it's stuck in an endless loop... why is that?

// from main():
// printString("hello");

void printString(char *ch)
{
    while (*ch = getchar(), *ch >= 0)
    putchar(*ch);
}
Was it helpful?

Solution

Based on your description, you just want:

void printString(char *ch)
{
  while(*ch) {
     putchar(*ch);
     ch++;
  }
}

Your original function:

void printString(char *ch)
{
    while (*ch = getchar(), *ch >= 0)
    putchar(*ch);
}

Does a lot of stuff:

  1. reads characters from stdin
  2. stores the character read from stdin into the first char pointed to by ch (this might not even work if you pass in a string literal.
  3. writes characters to stdout.
  4. Terminates when the read character is < 0 (this won't work on some platforms. Since the result is stored in a char you can't distinguish between EOF and a valid character. ch should be an int, as getchar() returns an int so you can check for EOF)

OTHER TIPS

getchar() reads user input from stdin. If you want to print the string being passed in then there's no need for getchar().

Let's take it step by step. The loop you have reads one character a time from stdin until it reaches end-of-file. That's what the ch >= 0 test checks for: keep reading as long as we're getting valid characters. For printing the characters of a string, the condition changes. Now a valid character is anything that's not NUL ('\0'). So we'll change the loop condition to:

while (*ch != '\0')

Next is figuring out the loop body. putchar(*ch) is fine; we'll leave that there. But without getchar() we have to figure out what the equivalent statement to "get the next character" is.

That would be ch++. This advances the ch pointer to the next character in the string. If we put that at the end of the loop then we'll print a character, advance one space, and then check if the next character is non-NUL. If it is then we print it, advance, and check.

while (*ch != '\0') {
    putchar(*ch);
    ch++;
}

What happens here is the following:

  1. in the function main you call printString with a pointer to the string "hello"
  2. the printString function attempts to read a character with getchar()
  3. and save that character in the place of the 'h'

The rules of the language say that attempting to change that 'h' is Undefined Behaviour. If you're lucky, your program crashes; if you're very unlucky it will appear the program works.

In short: getchar() is used for reading; putchar() is used for writing.

And you want to write 5 letter: 'h', 'e', 'l', 'o', and another 'o'.

    hello
    ^            ch is a pointer
    ch           *ch is 'h' -- ch points to an 'h'

Is there something after that last 'o'? There is! A '\0'. The zero byte terminates the string. So try this (with printString("hello");) ...

void printString(char *ch)
{
    putchar(*ch); /* print 'h' */
    ch = ch + 1;  /* point to the next letter. */
                  /* Note we're changing the pointer, */
                  /* not what it points to: ch now points to the 'e' */
    putchar(*ch); /* print 'e' */
    ch = ch + 1;  /* point to the next letter. */
    putchar(*ch); /* print 'l' */
    ch = ch + 1;  /* point to the next letter. */
    putchar(*ch); /* print 'l' */
    ch = ch + 1;  /* point to the next letter. */
    putchar(*ch); /* print 'o' */
    ch = ch + 1;  /* point to the next letter. What next letter? The '\0'! */
}

Or you can write that in a loop (and call from main with different arguments) ...

void printString(char *ch)
{
    while (*ch != '\0')
    {
        putchar(*ch); /* print letter */
        ch = ch + 1;  /* point to the next letter. */
    }
}

I would just do printf("%s",str); or puts(str);

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top