How Do I Print A String In C.....?

B

blackneos940

Guest
First, the Code:
Code:
/*This is a rather Geeky POS System, which is Open Source. It is released under the GPL V2, or, at your option, any LATER Version. :)*/

#include <stdio.h>

#include <stdlib.h>

int main(void)

{
  char item_input[200];

  /*This is where the User enters the item to be checked out.*/

  printf ("Enter Grocery Item Here:\n");

  char* end_item_entry;

  while (getchar() != 'q')

  {
    scanf ("%s\n", &item_input);

    printf ("%s\n", item_input);

  }

  return 0;

}
Basically, it's a POS System, and I want it to Print whatever was entered..... :) The only problem is, it Prints it, but leaves off the first Letter..... :( For example, if I type "String", it will Print "tring"..... This is very odd..... :\ When I change the "getchar()" part to "while (1 == 1)" to test it, it comes out fine..... When I exit the Program.... :( Why is this.....? How can I make it Print out the Items without having to exit.....? I also want to be able to watch for a Character Input so that the Program knows if the User wants to stop adding items..... Thanks for any help guys....... :)
 


R

ryanvade

Guest
First, the Code:
Code:
/*This is a rather Geeky POS System, which is Open Source. It is released under the GPL V2, or, at your option, any LATER Version. :)*/

#include <stdio.h>

#include <stdlib.h>

int main(void)

{
  char item_input[200];

  /*This is where the User enters the item to be checked out.*/

  printf ("Enter Grocery Item Here:\n");

  char* end_item_entry;

  while (getchar() != 'q')

  {
    scanf ("%s\n", &item_input);

    printf ("%s\n", item_input);

  }

  return 0;

}
Basically, it's a POS System, and I want it to Print whatever was entered..... :) The only problem is, it Prints it, but leaves off the first Letter..... :( For example, if I type "String", it will Print "tring"..... This is very odd..... :\ When I change the "getchar()" part to "while (1 == 1)" to test it, it comes out fine..... When I exit the Program.... :( Why is this.....? How can I make it Print out the Items without having to exit.....? I also want to be able to watch for a Character Input so that the Program knows if the User wants to stop adding items..... Thanks for any help guys....... :)
It looks like the getchar is grabbing the first character, so then the scanf never reads it. I personally prefer fgets rather than scanf, so here is my implementation.
Code:
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
        char* entry = malloc(sizeof(entry) * 255);
        while(1)
        {
                printf("Please enter an item: ");
                fgets(entry, 255, stdin);
                printf("%s\n", entry);
        if(*entry == 'q')
          {
                break;
          }
        }
        free(entry);
}
Code:
[email protected]:~$ ./main
Please enter an item: item
item

Please enter an item: thing
thing

Please enter an item: q
q
 
B

blackneos940

Guest
It looks like the getchar is grabbing the first character, so then the scanf never reads it. I personally prefer fgets rather than scanf, so here is my implementation.
Code:
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
        char* entry = malloc(sizeof(entry) * 255);
        while(1)
        {
                printf("Please enter an item: ");
                fgets(entry, 255, stdin);
                printf("%s\n", entry);
        if(*entry == 'q')
          {
                break;
          }
        }
        free(entry);
}
Code:
[email protected]:~$ ./main
Please enter an item: item
item

Please enter an item: thing
thing

Please enter an item: q
q
Thanks, good sir!..... :3 I think I'll use that Code instead, and add your Name to a Comment, as a recognition tribute!!..... ^^
 
R

rstanley

Guest
It looks like the getchar is grabbing the first character, so then the scanf never reads it. I personally prefer fgets rather than scanf, so here is my implementation.
Code:
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
        char* entry = malloc(sizeof(entry) * 255);
        while(1)
        {
                printf("Please enter an item: ");
                fgets(entry, 255, stdin);
                printf("%s\n", entry);
        if(*entry == 'q')
          {
                break;
          }
        }
        free(entry);
}
Code:
[email protected]:~$ ./main
Please enter an item: item
item

Please enter an item: thing
thing

Please enter an item: q
q
Sorry @ryanvade, but there are some issues with your code.

Code:
char* entry = malloc(sizeof(entry) * 255);
entry is a "char *", not a char!
"sizeof(entry)" (Pointer to char) on my system is 8, not 1!
"sizeof(char)" is guaranteed to be 1 by the standard.
Your code allocates 2040 bytes, NOT 255!

No need for malloc() in this case but if you did, then it should be:
Code:
#define DIM 255
...
char* entry = malloc(DIM);
Try the following version:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>  /* For the tolower() function. */

/* Don't use "Magic Numbers" in your code */
#define DIM 255

/* If you don't need Command Line Arguments, use this version of main() */
int main(void)
{
    /* No need to use malloc() here */
    char entry[DIM] = ""; /* Plus, always initialize the array, and all local variables */

    while(1)
    {
      printf("Please enter an item: ");
      fgets(entry, DIM, stdin);

      /* Allow the user to enter, 'Q' or 'q' */
      if(tolower(*entry) == 'q')
      {
          break;
      }
      else
      {
        printf("%s\n", entry);
      }
    }
}
The use of fgets() is far superior to scanf(), but please note that the newline char is brought into "entry". In real life code, you will need to remove that newline from "entry" before using.
 
R

ryanvade

Guest
Sorry @ryanvade, but there are some issues with your code.

Code:
char* entry = malloc(sizeof(entry) * 255);
entry is a "char *", not a char!
"sizeof(entry)" (Pointer to char) on my system is 8, not 1!
"sizeof(char)" is guaranteed to be 1 by the standard.
Your code allocates 2040 bytes, NOT 255!

No need for malloc() in this case but if you did, then it should be:
Code:
#define DIM 255
...
char* entry = malloc(DIM);
Try the following version:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>  /* For the tolower() function. */

/* Don't use "Magic Numbers" in your code */
#define DIM 255

/* If you don't need Command Line Arguments, use this version of main() */
int main(void)
{
    /* No need to use malloc() here */
    char entry[DIM] = ""; /* Plus, always initialize the array, and all local variables */

    while(1)
    {
      printf("Please enter an item: ");
      fgets(entry, DIM, stdin);

      /* Allow the user to enter, 'Q' or 'q' */
      if(tolower(*entry) == 'q')
      {
          break;
      }
      else
      {
        printf("%s\n", entry);
      }
    }
}
The use of fgets() is far superior to scanf(), but please note that the newline char is brought into "entry". In real life code, you will need to remove that newline from "entry" before using.
I realize it is a char* not a char. fgets requires a char* for the buffer. Yes, using a char array works but I was following the man page for fgets and its recommended use.
Code:
char *fgets(char *s, int size, FILE *stream);
http://stackoverflow.com/questions/...tiply-by-sizeof-char-when-manipulating-memory
 
R

rstanley

Guest
I realize it is a char* not a char. fgets requires a char* for the buffer. Yes, using a char array works but I was following the man page for fgets and its recommended use.
Code:
char *fgets(char *s, int size, FILE *stream);
http://stackoverflow.com/questions/...tiply-by-sizeof-char-when-manipulating-memory
When using malloc() to allocate an array, you should use "sizeof(array[0]) for any type EXCEPT a "char"!!! Why? Because the C programming Language Standards, for C89, C99, or C11 specifies that the Size of a char is ALWAYS one, and only one!!! The number of bits in any byte for most current O/S's is Eight, BUT on some older, or more obscure O/S's, it might be more or less than eight.

Since the name of any array is a pointer to the first element of the array, for the following code:
Code:
#define DIM 255
...
// Either:
char entry[DIM];
// or
char *entry = malloc(DIM);

// is correct for use in:

fgets(entry, DIM, stdin);
Also, with the use of malloc(), you need to check the return value (Address) from malloc() to insure that valid memory was allocated, before attempting to use the memory. (Never ass/u/me)! ;^)

In the code in question, the use of malloc() to allocate an array of 255 chars to use as an input buffer, would be the equivalent of swatting flies with a Howitzer! Extremely satisfying, but overkill, (as well as being very destructive!) ;^)
 
Last edited:
B

blackneos940

Guest
When using malloc() to allocate an array, you should use "sizeof(array[0]) for any type EXCEPT a "char"!!! Why? Because the C programming Language Standards, for C89, C99, or C11 specifies that the Size of a char is ALWAYS one, and only one!!! The number of bits in any byte for most current O/S's is Eight, BUT on some older, or more obscure O/S's, it might be more or less than eight.

Since the name of any array is a pointer to the first element of the array, for the following code:
Code:
#define DIM 255
...
// Either:
char entry[DIM];
// or
char *entry = malloc(DIM);

// is correct for use in:

fgets(entry, DIM, stdin);
Also, with the use of malloc(), you need to check the return value (Address) from malloc() to insure that valid memory was allocated, before attempting to use the memory. (Never ass/u/me)! ;^)

In the code in question, the use of malloc() to allocate an array of 255 chars to use as an input buffer, would be the equivalent of swatting flies with a Howitzer! Extremely satisfying, but overkill, (as well as being very destructive!) ;^)
Hehe, you're funny, Mr. Penguin..... :D Anywho, I'll study what you said, so I can get a better idea of how to make my Program more safe..... :3 Also, I suspect that @ryanvade is better in Python than in C....... :)
 

samK

New Member
Credits
200
  1. int main() { char z[100];
  2. printf("Enter a string\n"); gets(z);
  3. printf("The string: %s\n", z); return 0; }
 

JasKinasis

Well-Known Member
Credits
3,146
  1. int main() { char z[100];
  2. printf("Enter a string\n"); gets(z);
  3. printf("The string: %s\n", z); return 0; }
Nice necropost!

FYI gets should not be used because it does not bounds-check the input. Using gets, it would be possible for a user to enter more than 99 characters, exceeding the array bounds and overflowing the buffer.
The buffer size is 100, so would have space for 99 characters plus the terminating null character.
And even if your snippet was compiled using gcc’s buffer overflow protection, the program would still crash with an error in the event that the user enters more than 99 characters.

Rstanleys posts regarding fgets are much better solutions because fgets IS bounds checked. It will not allow the user to overflow the buffer.
 


Members online

No members online now.

Latest posts

Top