user14158054
user14158054

Reputation:

Unwanted chars in output

What I'm trying to do is learn how to use pointers. Though the outputs of the this small program are controversial:

OUTUPTS

hello World!
[STRING]:hello World!
³a

y = x^2+y^2+2ax+2by+c
[STRING]:y = x^2+y^2+2ax+2by+c
­v¿▄▲_

Everything is fine, exept the last chars at the end. I run the program multiple times with differnt inputs: the string remais fine, but still the chars are there, changing some times.

/*C program to input and print arrays using pointers*/
#include <stdio.h>
#define STACK   1000

int main(){
  /*Variables*/
  char t[STACK];
  char *pt;
  int c, i;
  /*Input*/
  for(i = 0, pt = t; *pt < STACK && *pt != '\n' && (c = getchar()) != EOF; i++){
     *(pt + i) = c;
     if(*pt == '\n')
        *(pt++) = '\0';
}
 /*Print*/
 printf("[STRING]:%s", t);

}

If you know what the error is, please give me an hint :> Thanks in advance.

Upvotes: 0

Views: 67

Answers (2)

David C. Rankin
David C. Rankin

Reputation: 84569

In addition to the links provided to pointer basics in the comment, you are confusing yourself by overloading your loop definition which can obscure individual tests and assignments.

The key in taking any character input while filling an array is knowing when to stop taking input in order to protect your array bounds. Since you must reserve room at the end of your input for the nul-terminating character '\0' (or just plain 0), the last array index you can fill with input is STACK-2. The easiest way to properly limit input is simply to keep a counter, initialized to zero at the start.

You cannot use *pt < STACK as a test to determine when the array is full (or for anything else for that matter). Since *pt is type char its value will always be less than 1000 making the comparison *pt < STACK superfluous.

An array declaration is complete when made, so to initialize pt, you can simply do that at the time of declaration, e.g.

#include <stdio.h>

#define STACK   1000                /* good job defining a constant! */

int main (void) {
    
    char t[STACK], *pt = t;         /* array and pointer */
    ...

Your declaration of c as type int is correct and required to properly test against EOF. Do not get in the habit of using *(pt + i) for pt[i]. Yes, they are equivalent, but the first is less readable for many.

To structure your read, you can simply do:

    ...
    int c;
    size_t n = 0;                   /* use counter */
    
    fputs ("enter characters, [Enter] when done:\n\n[INPUT ]: ", stdout);
    
    /* while t not full and getchar not EOF */
    while (n + 1 < STACK && (c = getchar()) != '\n' && c != EOF) {
        *pt++ = c;                  /* assign character to pointer, advance */
        n++;                        /* increment counter */
    }
    ...

All that remains is nul-terminating t and outputting the results, e.g.

    ...
    *pt = 0;                        /* nul-terminate t */
    
    printf("[STRING]: %s\n", t);    /* output result */
}

Altogether, you would have:

#include <stdio.h>

#define STACK   1000                /* good job defining a constant! */

int main (void) {
    
    char t[STACK], *pt = t;         /* array and pointer */
    int c;
    size_t n = 0;                   /* use counter */
    
    fputs ("enter characters, [Enter] when done:\n\n[INPUT ]: ", stdout);
    
    /* while t not full and getchar not EOF */
    while (n + 1 < STACK && (c = getchar()) != '\n' && c != EOF) {
        *pt++ = c;                  /* assign character to pointer, advance */
        n++;                        /* increment counter */
    }
    
    *pt = 0;                        /* nul-terminate t */
    
    printf("[STRING]: %s\n", t);    /* output result */
}

Example Use/Output

$ ./bin/getchar_pt
enter characters, [Enter] when done:

[INPUT ]: My dog has fleas, my cat has none!
[STRING]: My dog has fleas, my cat has none!

Look things over and let me know if you have further questions.

Upvotes: 2

Hancel Lin
Hancel Lin

Reputation: 375

#include <stdio.h>
#define STACK   1000

int main(){
    /*Variables*/
    char t[STACK];
    char *pt;
    int c, i;
    /*Input*/
    for(i = 0, pt = t; i < STACK && *(pt + i) != '\n' && (c = getchar()) != EOF; i++) { 
       // If the array is out of bounds, you should use i to judge, your pt has not changed, you should add i to judge again 
        *(pt + i) = c;
    }
    *(pt + i) = '\0'; // Add zero char at the end after exiting the loop 
    /*Print*/
    printf("[STRING]:%s", t);
    return 0; // Please note that your main function return value is int 
}

Upvotes: 0

Related Questions