在C中打印时,为什么会出现此空白?

时间:2012-02-16 02:16:53

标签: c printf strtok

我只是将一个句子标记并将其放入堆栈然后将每个标记弹回并打印内容。一切都按照它应该的方式工作,除了我打印第一个标记后得到一个空行。它只是在我打印%s时才会这样做,如果我使用其他任何信息是垃圾,但我没有得到一个空行。我已经尝试过一个小函数来确保删除fgets抓取的换行符。任何帮助表示赞赏。

#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;
} 

3 个答案:

答案 0 :(得分:2)

当您使用fgets时,您最后会读到一行包括 '\n'。当您对字符串进行标记时,此'\n'位于最后一个标记中。当您打印此令牌时,也会打印'\n'。您应该手动删除它,或使用scanf

编辑:来自man fgets

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

答案 1 :(得分:0)

我尝试运行你的代码,从它的外观来看,它正在打印当你按Enter键提交输入时出现的换行符。

由于你的代码从堆栈弹出,并以相反的顺序打印令牌,最后一个令牌上的换行符仍然存在,这就是为什么它在你的第一个令牌之后总是换行。

答案 2 :(得分:0)

完成输入字符串后,换行符来自fgets函数。请参阅参考here

  

从流中读取字符并将它们作为C字符串存储到str中,直到读取了(num-1)个字符或者到达了换行符或文件结尾,以先到者为准。   换行符使fgets停止读取,但它被认为是有效字符,因此它包含在复制到str的字符串中。   在读取字符后,空字符会自动附加在str中,以表示C字符串的结尾。