0

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 "%31s"
#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

6
  • 2
    scanf("%s", start) This is wrong. start points to a single char instead of a buffer for a string. Same for end. Commented Apr 4, 2022 at 8:53
  • 1
    start and end are pointers to char, but they are not really strings; each points to a single character in main. scanf("%s")` can only scan words of non-zero length, but since it must store the null terminator, one char isn't enough. Use a reasonably sized array of chars, which should be a local variable of InputWords. Commented Apr 4, 2022 at 8:53
  • You use assert, printf, scanf which all require includes. MAX_WORD_LENGTH is not defined. The bare minimum is to post code that compiles (IMHO). Commented Apr 4, 2022 at 8:58
  • Interface makes no sense... if you don't need n, start and end in calling code pass in the variables? Commented Apr 4, 2022 at 9:05
  • 1
    Do you expect start and end word to be part of words? You don't check. What should happen if they are not? What is the definition of "symbol"? Is it just '#' or is it an example of a set values? Commented Apr 4, 2022 at 9:19

2 Answers 2

2

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("%31s", start) == 1 && *start != '#') {
          printf("Enter end word: ");
          scanf("%31s", end);
      }
    

Here is a modified version:

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

#define MAX_WORD_LENGTH 31
#define FORMAT_STRING "%31s"

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;
}
Sign up to request clarification or add additional context in comments.

2 Comments

Perhaps use ## to form "%31s" from MAX_WORD_LENGTH? But that may be too advanced for OP.
@chux-ReinstateMonica: I considered this option, but indeed thought it was too advanced for the OP's skill level. Grouping both definitions and making MAX_WORD_LENGTH the length, not the size underscores the need to keep them in sync.
0

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

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

#define FORMAT_STRING "%31s"
#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;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.