سؤال

I am just tokenizing a sentence and putting it onto a stack and then popping each token back off and printing the contents. Everything works the way it should except I am getting a blank line after it prints the first token. It only seems to do this when I am printing a %s if I use anything else the information is garbage but I dont get a blank line. I already tried a small function to ensure that strips out the newline character that fgets grabs. Any help is appreciated.

#define BUFFER_SIZE 100
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// self-referential structure
struct stackNode
{   
   char *cData;
   struct stackNode *pNext;
};

typedef struct stackNode StackNode;
typedef StackNode *StackNodePtr;

// function prototypes
void push( StackNodePtr *pTop, char *cInfo );
char* pop( StackNodePtr *pTop );
int isEmpty( StackNodePtr pTop );
void printStack( StackNodePtr pCurrent );


int main(void)
{
    char sInput[BUFFER_SIZE];
    StackNodePtr pStack = NULL;
    char *pToken = NULL;
    int iIndex;

    printf("Please enter a word to be tokenized\n");

    fgets(sInput, BUFFER_SIZE, stdin);

    pToken = strtok(sInput, ", ");

    while(pToken != NULL)
    {
        push(&pStack, pToken);
        pToken = strtok(NULL, " ,");
    }

    while (isEmpty(pStack) == 0)
    {
        printf("%s\n", pop(&pStack));
    }
    return 0;
}

// Insert a node at the stack top
void push( StackNodePtr *pTop, char *cInfo )
{ 
   StackNodePtr pNew;

   pNew = malloc( sizeof( StackNode ) );

   if ( pNew != NULL )
   {   
      pNew->cData = cInfo;
      pNew->pNext = *pTop; // insert at top of stack
      *pTop = pNew;
   }
   else
   {
      printf( "%d not inserted. No memory available.\n", cInfo );
   }
} 

// Remove a node from the stack top
char* pop( StackNodePtr *pTop )
{ 
   StackNodePtr pTemp;
   char *cPopValue;

   pTemp = *pTop; // attach a pointer to element to be removed
   cPopValue = ( *pTop )->cData; 
   *pTop = ( *pTop )->pNext; // remove at top of stack
   free( pTemp ); // release this memory and set it free!

   return cPopValue;
}

int isEmpty( StackNodePtr pTop )
{ 
   return pTop == NULL;
} 
هل كانت مفيدة؟

المحلول

When you use fgets, you read a line including the '\n' in the end. when you tokenize the string, this '\n' is in the last token. when you print this token, you print the '\n' too. You should remove it by hand, or use scanf.

EDIT: from man fgets:

Reading stops after an EOF or a newline.
If a newline is read, it is stored into the  buffer.

نصائح أخرى

I tried running your code, and from what it looks like, it is printing the newline character that comes from when you press enter to submit the input.

Since your code is popping them off the stack, and printing the tokens in reverse order, the newline character that was on the last token is still there, that's why it's always a newline after your first token.

The newline character comes from the fgets function when you finish entering your string. See the reference here:

Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or a the End-of-File is reached, whichever comes first. A newline character makes fgets stop reading, but it is considered a valid character and therefore it is included in the string copied to str. A null character is automatically appended in str after the characters read to signal the end of the C string.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top