1

It doesn't put the correct amount of array elements, and reads less than supposed to and when 1 becomes true it spits either NULL, or 0. becomes true it doesn't print the random name

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

int main()
{
    int i;
    char cast1;
    int cast2;

    printf("Choose array length: ");
    scanf("%c", &cast1);
    cast2 = atoi(&cast1);
    char parr1[cast2];

    for(i=0; i<cast1; i++)
    {
        char tempchar;
        printf("Name to insert to array: ");
        scanf("%s", &tempchar);
        parr1[i] = tempchar;
    }

    int range = sizeof(parr1) / sizeof(parr1[0]);
    int tempint;
    int logic;
    char answer;

    printf("Would you like to generate a new name?[y1/n2]: ");
    scanf("%d", &logic);
    if(logic==1)
    {
        answer='y';
    }
    else if(logic==2)
    {
        answer='n';
    }

    while(answer=='y')
    {
        tempint = rand()%range;
        printf("%c", parr1[tempint]);
    }
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 3
    You never update `answer` in the `while` loop, so it's an infinite loop. – Barmar Jun 15 '22 at 19:29
  • `atoi` expects a string; maybe you meant to use `cast2 = cast1 - '0';`. – Neil Jun 15 '22 at 19:29
  • 2
    Your `atoi` call has undefined behavior, since you're passing it a pointer to a single character, which is not guaranteed to be followed by a null character. You need to pass it the address of a null-terminated character array, not a single character. – Tom Karzes Jun 15 '22 at 19:29
  • 2
    `scanf("%c", &cast1); cast2 = atoi(&cast1);` Why not just `scanf("%d", &cast2)`? – 001 Jun 15 '22 at 19:30
  • Why are you reading just a single character for the array length? – Barmar Jun 15 '22 at 19:30
  • 2
    `%s` requires the argument to be a pointer to a character array. You're passing a pointer to a single `char`, which doesn't have room for the null terminator. – Barmar Jun 15 '22 at 19:30
  • Not checking the return value of `scanf` is always a bug. Also, where is the random name? – Neil Jun 15 '22 at 19:33
  • I would recommend to read some C tutorials on strings, arrays, pointers. Too many problems with this code – OldProgrammer Jun 15 '22 at 19:35
  • 1
    using an incorrect format specifier in `scanf` or `printf` is always a source of [undefined behavior](https://en.cppreference.com/w/cpp/language/ub). For this reason alone, your code contains several opportunities for unwanted randomness, which is partly preventing the desired randomness you are attempting. Adding to that that `srand` is not being called. This too will cause `rand` to be even less random than it normally is. – ryyker Jun 15 '22 at 19:47
  • I see the user asked for a name and then it spits back the same name. Are you sure it's doing what you intend? Technically, that isn't really [random](https://codereview.stackexchange.com/q/269448). – Neil Jun 15 '22 at 19:54

1 Answers1

0

The comments have highlighted many issues. Here are some of the same, some more, and some solutions.

The const char * argument to atoi does not mean a pointer to any character, but rather a pointer to a null-terminated sequence of non-zero bytes: a string.

On scanf, briefly:

  • Always check the return value is the expected number of conversions. Failing to do so means operating on indeterminate values.
  • %d reads a signed integer, %u reads an unsigned integer.
  • %c reads a single character. Prefixing this specifier with a space ( %c) causes it to skip leading whitespace.
  • %s reads a string. Its argument must be a pointer to a buffer that can store multiple characters, with room for a null-terminating byte (hint: an array). Always limit this specifier to the size of the buffer, minus one.
char buffer[128];
if (1 != scanf("%127s", buffer))
   /* uh oh */;

Had it worked, char parr1[cast2]; would only be able to a single string. You need an array of arrays to store multiple strings.

When creating a variable-length array, care must be taken to ensure the size is always a positive, non-zero integer that will not expend too much memory.

Calling rand without first calling srand (once) will lead to the same results every time you run the program.

Reading an integer (scanf("%d", &logic);), and then using that value to determine the value of another variable (answer), only to use the second value the same way you would have used the first is ... redundant.

while(answer=='y') will never stop, as answer does not change inside the loop.


This is, more-or-less, the program you were attempting to write.

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

int main(void)
{
    unsigned length;

    printf("Choose array length: ");

    if (1 != scanf("%u", &length) || 0 == length || length > 50)
        return EXIT_FAILURE;

    char names[length][100];

    for (unsigned i = 0; i < length; i++) {
        printf("Name to insert to array: ");

        if (1 != scanf("%99s", names[i]))
            return EXIT_FAILURE;
    }

    srand((unsigned) time(NULL));

    while (1) {
        char answer;

        printf("Would you like to generate a new name? (y1 / n2): ");

        if (1 != scanf(" %c", &answer))
            return EXIT_FAILURE;

        if (!strchr("y1", answer))
            break;

        puts(names[(unsigned) rand() % length]);
    }
}

Input file for testing (./a.out < input):

10
one
two
three
four
five
six
seven
eight
nine
ten
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyn

Output, abbreviated:

Would you like to generate a new name? (y1 / n2): one
Would you like to generate a new name? (y1 / n2): four
Would you like to generate a new name? (y1 / n2): nine
Would you like to generate a new name? (y1 / n2): ten
Would you like to generate a new name? (y1 / n2): five
Would you like to generate a new name? (y1 / n2): one
Would you like to generate a new name? (y1 / n2): seven
...
Oka
  • 23,367
  • 6
  • 42
  • 53