All right this is easy and for some reason im having trouble. Im workng on a Pig Latin program but right now all I want help with is getting an entire sentence to print out. I first tried to do this

char pig_latin() 
{ 
char sentence[100]; 

printf("Enter a sentence\n"); 
scanf("%s", sentence); 
printf("Sentence was: %s\n", sentence); 
}

of course after reading past posts and thinking about it I realize that will only print the first word. So i found this in a post and tried it (and some other attempts using gets().

char Sentence[50]; 

printf("Enter String >"); 
gets(Sentence);

I also read that I should use fgets() instead of gets() and I understand why. The problem im having is how exactly to use it. Here is my last try but it doesnt allow the user to input a sentence. And I was told not to use scanf by some other people.

char sentence[80];

  printf("Enter a sentence in all CAPS to be translated into piglatin:\n");

  fgets(sentence, sizeof(sentence), stdin);

  printf("Heres the sentence: %s\n", sentence);

>required to use gets
Slap your teacher for me. He's a moron. There's never a good reason to use gets, and anyone who requires it clearly has no idea how C works.

Well im still having a problem wraping my head around this and im stuck on what(how) I should do. here is what I have wrote so far

char pig_latin() 
{ 

  int counter; 

  char sentence[MAX]; 
  char *pt; 

  printf("Enter a sentence to be translated into piglatin:\n"); 
  gets(sentence); 

  for( counter = 0; counter <= MAX; counter++){ 
    if(sentence[counter]=='\0')break; 
  } 


  while(gets(sentence) != '\0') 
    {        puts(sentence); 
    printf("\n"); 
    }

The for and if statement is supposed to count how many words are in the sentence. I am trying to follow my lab instuctors but both of them say different things and im beyond confused. This is what one of them wrote out :

const int MAX_SIZE = 200; 
char* input[MAX_SIZE]; 
char* work[MAX_SIZE]; 
char* output[MAX_SIZE]; 

int length= 0; 

for(int size_input=0; size_input<= MAX_SIZE; size_input++) 
{ 
if(input [size_input]=='\0') break; 
if(in range){ 
work[size_input]= input[size_input]; 
length++ 
} 
} 
size_input will equal length - Null char 
work will contain copy of input to '\0'

He didnt explain things very well (or i just did not following him) and I was hoping that someone could explain it a little better. He said this was supposed to count the number of words in the sentence and like I said Im having problems translating this into something that I can use. I have no problem starting completely over if someone had something else they think I should try.


Also, now im not sure if I HAVE to use gets but I was told by someone else that fgets is for reading from a file and gets is for reading from a keyboard. Im still waiting for a reply on the gets v.s fgets from the teacher

>for(int size_input=0; size_input<= MAX_SIZE; size_input++)
*sigh* This is a classic and very well known error. Array indices go from 0 to size - 1, so stopping the loop at <= MAX_SIZE means that the loop writes beyond the last index in the array. Now I really wonder about the competence of your teachers.

>fgets is for reading from a file and gets is for reading from a keyboard
gets defaults to reading from stdin while fgets does not. However, gets is a throwback from the original portable C library (over 30 years old) and definitely shows signs of age. For example, there's no way to make gets safe:

char buffer[15];

gets ( buffer );

If stdin contains more than 14 characters before a newline, gets will still try to read them all and the effect is the same as that stupid loop one of your teachers gave you. The boundaries of the array or overwritten and all manner of problems show up. Furthermore, there's no way to avoid this problem with gets.

fgets, on the other hand, allows you to specify a limit on the number of characters to read:

fgets ( buffer, sizeof buffer, stdin );

sizeof returns 15, so gets will always stop after reading 14 characters even if a newline isn't found.

>Im still waiting for a reply on the gets v.s fgets from the teacher
I recommend that you use fgets and if you get any lip about it, send your teacher here to talk to me. I'll be happy to chat rape him on the topic of his ignorance.

Here's a naive implementation that you may use to give yourself ideas:

#include <ctype.h>
#include <stdio.h>

int trim_whitespace ( char line[], int pos )
{
  while ( isspace ( line[pos] ) )
    ++pos;

  return pos;
}

int is_vowel ( int c )
{
  c = toupper ( (unsigned char)c );
  return c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U';
}

int pig_word ( char line[], int pos )
{
  char prefix[BUFSIZ];
  int i = 0;

  pos = trim_whitespace ( line, pos );

  /* Save prefix */
  while ( !is_vowel ( line[pos] ) )
    prefix[i++] = line[pos++];
  prefix[i] = '\0';

  /* Print remaining */
  while ( !isspace ( line[pos] ) )
    putchar ( line[pos++] );

  /* Print prefix and suffix */
  printf ( "%say ", prefix );

  return pos;
}

void pig_latin ( char line[] )
{
  int pos = 0;

  while ( line[pos] != '\n' && line[pos] != '\0' )
    pos = pig_word ( line, pos );
}

int main ( void )
{
  char line[BUFSIZ];

  printf ( "Enter a sentence: " );
  fflush ( stdout );

  if ( fgets ( line, sizeof line, stdin ) != NULL )
    pig_latin ( line );

  return 0;
}

WOW, Thanks for your help. Yeah I not to happy with my instructors, I learn better by examples then what ever it is that they are doing.Thank you for taking the time to give a great example to work from.

Yeah basically, fgets allows you to set the limit of characters inputted while gets does not.

I do have a few questions if Narue wouldn't mind helping me. If i use fgets(sentance, 10, stdin) then printf ("%s12345", sentance); and the user inputted "Hello" i would have "Hello 12345", but i want "Hello12345". How do i get it to printout only the sentance and not the spaces. gets() would not give me that problem and as much as i hate it I have to complete an assignment using gets because of it (due today). Another question I have is I am trying to get a full sentance but when i use spaces the program does not function properly.

printf ("Enter the total for new account %d: ", acc[*tcount-1]); /*prompt for account name*/
do{
gets(title[*tcount-1]);
if (strlen(title[*tcount-1]) > 30){
printf ("**Title entered is longer than 30 characters\n");
printf ("Please reenter : ");
error='t';
}
}while (error='t');

Title is a 2d array. When i enter a sentance with spaces (and is under the array limit 40-1) then hit enter i am stuck in the scanf option the program does not continue. What am i doing wrong? Thanks

>I do have a few questions if Narue wouldn't mind helping me.
Then it's fortunate that I'm still around five years after this thread ended previously.

>How do i get it to printout only the sentance and not the spaces.
Presumably you don't want the newline character that fgets stores and gets throws away. It's a simple matter, though not as convenient as gets:

if (fgets(s, sizeof s, stdin) != NULL) {
    char *newline = strchr(s, '\n');

    if (newline != NULL)
        *newline = '\0';
}

The idea is to search for a newline (there will only be one at the end, if any) and replace it with a string terminator.

>}while (error='t');
You accidentally used = for assignment instead of == for comparison.

Thanks a lot man really helped me. Because I forgot to put that extra '=' sign my loop went forever and wasn't continuing. Thanks to you i now used fgets() . I do have another question for you since you are the man, fgets(s, 10, stdin) user enters in 12 characters. The program uses the 12 characters (including \n ) and applies it to the rest of input in my other program and really screws stuff up. Is there a way too if s[10] != \n then flush the rest of the input? I'm writing in C. Thank you once again.

>Is there a way too if s[10] != \n then flush the rest of the input?
Detecting such a situation is the reason why fgets stores the newline character instead of throwing it away. Though flushing the input stream for partial input isn't exactly the best idea. You should write your code to handle long lines:

#include <stdio.h>
#include <stdlib.h>

char *jgets(FILE *in)
{
#define JGETS_CHUNK 16

    char *buf = NULL;
    size_t cap = 0;
    size_t n = 0;
    int done = 0;
    int ch;

    for (;;) {
        if (n == cap) {
            char *save;

            cap += JGETS_CHUNK;
            save = realloc(buf, cap + 1);

            if (save == NULL)
                break;

            buf = save;
        }

        if ((ch = getc(in)) == '\n' || ch == EOF)
            break;

        buf[n++] = (char)ch;
    }

    if (buf != NULL)
        buf[n] = '\0';

    return buf;

#undef JGETS_CHUNK
}

int main(void)
{
    char *s;

    while ((s = jgets(stdin))[0] != '\0') {
        printf(">%s<\n", s);
        free(s);
    }

    return 0;
}

However, there are cases where simply tossing the remaining characters is a viable option. In that case, you can generally rely on the presence of either a newline character or EOF at the end of any input:

#include <stdio.h>
#include <string.h>

int main(void)
{
    char buf[5];

    while (fgets(buf, sizeof buf, stdin) != NULL) {
        char *newline = strchr(buf, '\n');

        if (newline != NULL)
            *newline = '\0';
        else {
            int ch;

            /* Flush remaining characters on the line */
            while ((ch = getc(stdin)) != '\n' && ch != EOF)
                ;
        }

        printf(">%s<\n", buf);
    }

    return 0;
}

Some may recommend fflush(stdin) to you for flushing the input stream, but don't take that advice. fflush isn't designed to work on input streams, only output streams.

This article has been dead for over six months. Start a new discussion instead.