Почему я получаю эту пустую строку при печати в C?


Я просто маркирую предложение и помещаю его в стопку, а затем убираю каждый маркер обратно и печатаю содержимое. Все работает так, как должно, за исключением того, что я получаю пустую строку после того, как он печатает первый маркер. Это только кажется, что делает это, когда я печатаю %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 tokenizedn");

    fgets(sInput, BUFFER_SIZE, stdin);

    pToken = strtok(sInput, ", ");

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

    while (isEmpty(pStack) == 0)
    {
        printf("%sn", 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 2

3 ответа:

Когда вы используете fgets, Вы читаете строку , включая '\n' в конце. когда вы маркируете строку, это '\n' находится в последнем маркере. когда вы печатаете этот маркер, вы также печатаете '\n'. Вы должны удалить его вручную или использовать scanf.

EDIT: from man fgets:

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

Я попробовал запустить ваш код, и, судя по тому, как он выглядит, он печатает символ новой строки, который появляется при нажатии клавиши enter для отправки ввода.

Поскольку ваш код извлекает их из стека и печатает маркеры в обратном порядке, символ новой строки, который был на последнем маркере, все еще там, поэтому он всегда является новой строкой после вашего первого маркера.

Символ новой строки берется из функции fgets после завершения ввода строки. Смотрите ссылку здесь:

Считывает символы из потока и сохраняет их в виде строки C в str до тех пор, пока не будут прочитаны символы (num-1) или не будет достигнута новая строка или конец файла, в зависимости от того, что наступит раньше. символ новой строки заставляет fgets прекратить чтение, но он считается допустимым символом и поэтому включается в строку, скопированную в str. Значение null символ автоматически добавляется в str после того, как символы считаны, чтобы сигнализировать конец строки C.