Ungets

I need to write in C a function ungets(s) that will push back an entire string onto the input. Should ungets know about buf and bufp or should it just use ungetch?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

#define BUFSIZE 100
char buf[BUFSIZE];
int bufp = 0;             /* next free position in buf */

  int getch(void)           /* get a (possibly pushed back) character */

{
	
	return (bufp > 0) ? buf[--bufp] : getchar();
	
}
	  
	  
  void ungetch(int c)	  /* push character back on input  */
  {
	  if (bufp >= BUFSIZE)
		  printf("ungetch: too many characters\n");
	  
	  else
		   buf[bufp++] = c;
  }
	  
	  
  



Here is how I would do it:

For each character in s

ungetch(c);

Any suggestions?

Last edited on
just use ungetch...

And what about the null-character at the end of the string, should it be pushed in as well?
Do I have to loop through the string?


1
2
3
4
5
6
7
8
9
10
11
12

void ungets(char s[])  
{
    int c;
		
    for (c = 0; c < strlen(s); c++)
			
    ungetch(c);
}	
		
		
  
Last edited on
> Do I have to loop through the string?

Yes. Probably in reverse. Something like this:

1
2
3
4
5
6
// header (add comments explaining usage)
#include <stdbool.h>

int my_getc() ;
bool my_ungetc( char c ) ;
bool my_ungets( const char* cstr ) ;


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// implementation

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

enum { BUFFSZ = 100 };
static char buffer[BUFFSZ] = {0};
static size_t next_pos = 0 ;  /* next free position in buf */

static bool empty() { return next_pos == 0 ; }
static size_t available() { return BUFFSZ - next_pos ; }
static char pop() { return empty() ? 0 : buffer[--next_pos] ; }
static bool push( char c ) { return available() ? ( buffer[next_pos++] = c ) : false ; }


int my_getc() { return empty() ? getchar() : pop() ; }

bool my_ungetc( char c ) { return push(c) ; }

bool my_ungets( const char* cstr )
{
    if( cstr == NULL ) return false ;
    const size_t len = strlen(cstr) ;
    if( len > available() ) return false ;

    // loop through the string and push in reverse order
    for( size_t i = 0 ; i < len ; ++i ) my_ungetc( cstr[ len-1-i ] ) ;
    return true ;
}
How do I test this ungets function?
Write test-cases and exercise the code with a test frame.

This may help you get started (it has just one test-case for ungets):
1
2
3
4
5
6
7
8
9
10
int main() // simple test driver
{
    const char a[] = "test ungets();" ;
    const char b[] = "test it once again." ;

    if( my_ungets(b) && my_ungetc( ' ' ) && my_ungets(a) )
        for( size_t i = 0 ; i < ( sizeof(a)-1 + 1 + sizeof(b)-1 ) ; ++i ) putchar( my_getc() ) ;

    if( my_ungetc('\n') ) putchar( my_getc() ) ;
}

http://coliru.stacked-crooked.com/a/a887fb21cff02100
Topic archived. No new replies allowed.