small medium large xlarge

Img_20161202_194300_pragsmall
12 Feb 2018, 12:04
Jared Blackburn (3 posts)

OK, I’ll post one more time before I give up on this forum as dead.

The problems in Chapter 2 are (as they should be) pretty easy in general, particularly with a high-level language like C# or Python. But some of the challenges can become tricky with less-high level language, “mid-level” languages like C often don’t have a simple way with standard libraries alone to get string input and mix it in with other data for output other than to use strings – after all, C function to take strings require a char pointer to passed to begin with this is fun, since it provides a problem with a completely obvious solution.

So, for the no declared variable I turned to recursion to keep the data in function parameters, and thus not technically declare a variable. The solutions are both flawed, and not things I’d do in a real application, but meet the technical requirements of the challenge:

Way one (leaks memory, but works):

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

char* getInput(char* previous, int size);
char* input(char* previous, int size);

/**
 * This is the first excercise (chapter 2, problem 1) from 
 * "Excercises for Programmers" by Brian P. Hogan, as 
 * completed by Jared Blackburn as an excercise.  If 
 * what it does isn't obvious, get the book.
 * 
 * This will use my own input function to rather than 
 * scanf() for one major (though in context unimportant) 
 * reason: this will not create any arrays that a user 
 * can overrun by typing too much (by accident, or 
 * intentionally as a hack).
 */
int main(int argc, char** argv) {
  printf("What's your name?\n");
  // Note this is actually *TERRIBLE* -- it works but leaks memory; 
  // fine for something like this but  would be idiotic in a real application!
  printf("%s%s%s", "Hello, ", getInput(0, 0), ", nice to meet you! :)\n");
  return 0;
}

/* 
 * Not safe / secure and kind of cheese things 
 * by making the variables parameters.  Hoevers, 
 * I don't think C or C++ has any other way to 
 * avoid using variables, either officially or 
 * stashed as function parameters.
 */
char* getInput(char* previous, int size) {
  if(!previous) {
    previous = malloc(256);
  }
  if((ungetc((char)getchar(), stdin) == '\r') 
	|| (ungetc((char)getchar(), stdin) == '\n')) {
    previous[size] = 0;
  } else {
    previous[size] = (char)getchar();
    getInput(previous, size + 1);
  }
  return previous;
}


char* input(char* previous, int size) {
}

Way two (no memory leak, but does intentionally reference a dangling pointer to quickly use output stored in freed memory):

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

char* getInput(char* previous, int size);
char* input(char* previous, int size);

/**
 * This is the first excercise (chapter 2, problem 1) from 
 * "Excercises for Programmers" by Brian P. Hogan, as 
 * completed by Jared Blackburn as an excercise.  If 
 * what it does isn't obvious, get the book.
 * 
 * This will use my own input function to rather than 
 * scanf() for one major (though in context unimportant) 
 * reason: this will not create any arrays that a user 
 * can overrun by typing too much (by accident, or 
 * intentionally as a hack).
 */
int main(int argc, char** argv) {
  printf("What's your name?\n");
  // This does not leak memory but is technically intentionally using 
  // (abusing) a dangling pointer, albeit in a very short time frame.
  printf("%s%s%s", "Hello, ", getInput(0, 0), ", nice to meet you! :)\n");
  return 0;
}

/* 
 * Not safe / secure and kind of cheese things 
 * by making the variables parameters.  Hoevers, 
 * I don't think C or C++ has any other way to 
 * avoid using variables, either officially or 
 * stashed as function parameters.
 */
char* getInput(char* previous, int size) {
  if(!previous) {
    previous = malloc(256);
    input(previous, size);
    free(previous);
  } else {
    input(previous, size);
  }
  return previous;
}


char* input(char* previous, int size) {
  if((ungetc((char)getchar(), stdin) == '\r') 
	|| (ungetc((char)getchar(), stdin) == '\n')) {
    previous[size] = 0;
  } else {
    previous[size] = (char)getchar();
    getInput(previous, size + 1);
  }
}

Thoughts anyone? A better way to do this?

You must be logged in to comment