Home > Software engineering >  C Input scanf() confusion
C Input scanf() confusion

Time:04-04

I want to use scanf() to read the input string.

If the input of printf("Enter start word: "); is the symbol #, it will not execute the next printf("Enter end word: "); command, and if the input is a word, then it will execute the next command. But I don't know how to determine whether the input is a symbol or a word.

Whatever I input, it still executes printf("Enter end word: ");

#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#define MAX_WORD_LENGTH 32
#define FORMAT_STRING "1s"
#define VERY_HIGH_VALUE 999999

char **InputWords(int *n, char *start, char *end) {
    printf("Enter a number: ");
    scanf("%d", n);    // the number of the input words
    char **words = malloc(sizeof(char *) * *n);
    assert(words != NULL);
    for (int i = 0; i < *n; i  ) {
        // allocate memory for the length of each input word
        words[i] = malloc(sizeof(char) * MAX_WORD_LENGTH);
        assert(words[i] != NULL);
        printf("Enter a word: ");
        scanf(FORMAT_STRING, words[i]);
    }

    printf("Enter start word: ");
    if (scanf("%s", start) == 1) {
        printf("Enter end word: ");
        scanf("%s", end);
    };

    printf("\n");
    printf("%d, %s, %s", *n, start, end);
    return words;
}

int main(void) {
    int n;
    char start, end;    //the start/end word, which is not necessary in stage 1-4
    char **words = InputWords(&n, &start, &end);   //create an array to store all input words
    return 0;
}

Moreover, when I add the code printf("%d", n); at the end of the function, the value of n becomes 0, although my input n is other number. When I add printf("%d, %s, %s", *n, start, end); at the last, the output shows

 Enter a number: 3
 Enter a word: bad
 Enter a word: ban
 Enter a word: dad
 Enter start word: bad
 Enter end word: ban
 110, an, ban

But in my input, the n = 3, start = ban and end = ban

CodePudding user response:

There are multiple problems in the code:

  • you pass the addresses of single char variables to InputWords instead of arrays of sufficient length. Reading a string into single char variables causes undefined behavior because scanf() will store at least 2 bytes into the destination array.

  • you should always specify the maximum number of characters to store into the destination arrays for scanf("%s", ...)

  • to prevent reading the end word you can simply test if the word read for start starts with a #:

      *end = *start = '\0';
      if (scanf("1s", start) == 1 && *start != '#') {
          printf("Enter end word: ");
          scanf("1s", end);
      }
    

Here is a modified version:

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

#define MAX_WORD_LENGTH 31
#define FORMAT_STRING "1s"

char **InputWords(int *np, char *start, char *end) {
    int n = 0;
    *np = 0;
    *start = *end = '\0';
    printf("Enter a number: ");
    if (scanf("%d", &n) != 1)    // the number of the input words
        return NULL;
    char **words = calloc(sizeof(char *), n);
    assert(words != NULL);
    for (int i = 0; i < n; i  ) {
        // allocate memory for the length of each input word
        words[i] = calloc(sizeof(char), MAX_WORD_LENGTH   1);
        assert(words[i] != NULL);
        printf("Enter a word: ");
        if (scanf(FORMAT_STRING, words[i]) != 1) {
            /* invalid input or premature end of file */
            while (i --> 0) {
                free(words[i]);
            }
            free(words);
            return NULL;
        }
    }

    printf("Enter start word: ");
    if (scanf(FORMAT_STRING, start) == 1 && *start != '#') {
        printf("Enter end word: ");
        scanf(FORMAT_STRING, end);
    }

    printf("\n");
    printf("%d, %s, %s\n", n, start, end);
    *np = n;
    return words;
}

int main() {
    int n;
    char start[MAX_WORD_LENGTH   1];  // the start word
    char end[MAX_WORD_LENGTH   1];    // the end word, which is not necessary in stage 1-4
    char **words = InputWords(&n, start, end);   //create an array to store all input words
    return 0;
}

CodePudding user response:

Try this and tell me what doesn't work now:

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

#define FORMAT_STRING "1s"
#define MAX_WORD_LENGTH 32

char **InputWords(int *n, char *start, char *end) {
    printf("Enter a number: ");
    scanf("%d", n);    // the number of the input words

    char **words = malloc((*n) * sizeof(*words));
    assert(words);
    for (int i = 0; i < *n; i  ) {
        // allocate memory for the length of each input word
        words[i] = malloc(MAX_WORD_LENGTH);
        assert(words[i]);
        printf("Enter a word: ");
        scanf(FORMAT_STRING, words[i]);
    }

    printf("Enter start word: ");
    if (scanf(FORMAT_STRING, start) == 1) {
        printf("Enter end word: ");
        scanf(FORMAT_STRING, end);
    };
    printf("\n%d, %s, %s", *n, start, end);
    return words;
}


int main(void){
    int n;
    char start[MAX_WORD_LENGTH];
    char end[MAX_WORD_LENGTH];
    char **words = InputWords(&n, start, end);   //create an array to store all input words
    // silence unused variables
    (void) n;
    (void) start;
    (void) end;
    return 0;
}
  • Related