Clayton Wahlstrom Clayton Wahlstrom - 3 months ago 26
C Question

scanf not reading mychars

I'm making a visual display for pointers by using a table. The first input for

length
works but
mychars
is not being read. I know that there's a new line after
scanf
but I don't know how it behaves. How is
mychars
's
scanf
parsed in my particular case?

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

int main() {
int length;
printf("Length? ");
scanf("%d", &length);

char *mychars = (char *)calloc(length, sizeof(char));

printf("mychars? ");
scanf("%[^\n]s", mychars);
printf("mychars is \"%s\"\n", mychars);
printf("pointer at %p\n", mychars);
if (strlen(mychars) == length) {
printf("Address Location Value\n");
int i;
for (i = 0; i < length; i++) {
printf("%-10p *(mychars+%02d) %3c\n", (mychars+i), i, *(mychars+i));
}
} else {
print("Not right length");
}
free(mychars);
return 0;
}

Answer

Do not use scanf(). It is evil. It does not handle problems well and is easy for learners to mis-use. Use fgets().

// untested code
int main(void) {
  size_t length;  // Use size_t for array sizes
  printf("Length? ");
  fflush(stdout); // Insure prompt is displayed before input.

  char buf[50];
  if (fgets(buf, sizeof buf, stdin) == NULL) return -1;
  if (sscanf(buf, "%zu", &length) != 1) return -1;

  char *mychars = malloc(length + 2);  // +1 for \n, +1 for \0
  if (mychars == NULL) return -1;

  printf("mychars? ");
  fflush(stdout);
  if (fgets(mychars, length + 2, stdin) == NULL) return -1;
  // lop off potential \n
  mychars[strcspn(mychars, "\n")] = 0;

  printf("mychars is \"%s\"\n", mychars);
  printf("pointer at %p\n", (void*) mychars);  // Use `void *` with %p

  if (strlen(mychars) == length) {
    printf("Address    Location        Value\n");
    size_t i;
    for (i = 0; i < length; i++) {
      printf("%-10p *(mychars+%02zu) %3c\n", (void*) (mychars + i), i, *(mychars + i));
    }
  } else {
    print("Not right length\n");  // add \n
  }
  free(mychars);
  return 0;
}