Почему я не могу ввести желаемое количество входов? - PullRequest
0 голосов
/ 14 июня 2019

Проблема заключается в том, чтобы вводить строки x количество раз, используя массив указателей. х - это значение, введенное пользователем. Я написал следующий код для того же. Но программа принимает только х-1 входы. Я вставил fflush (stdin), потому что я думаю, что scanf сначала использует ввод, но я не знаю откуда.

Я пробовал использовать get, но безрезультатно.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
    //code to take input in an array of pointers
    int x,i,j,length;
    char ch[50],*t;
    printf("How many names you want to sort:\n");
    scanf("%d",&x);
    char *names[x];
    char *p;
    printf("Enter the names:\n");
    for(i=0;i<x;i++)
    {
        fflush(stdin);
        scanf("%[^\n]s",ch);
        length = strlen(ch);
        p = (char *)malloc((length+1) * sizeof(char));
        strcpy(p,ch);
        names[i] = p;
    }
    return 0;
}

1 Ответ

3 голосов
/ 14 июня 2019

Зачем беспокоиться о сложных форматных строках, если вам это не нужно? Используйте fgets.

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

void err(const char * msg) {
    fprintf(stderr, msg);
    exit(1);
}

int main()
{
    int x,i;
    char ch[50];
    printf("How many names you want to sort:\n");
    if(!fgets(ch, 50, stdin)) err("Error reading line");
    if(sscanf(ch, "%d",&x) != 1) err("Could not read integer");

    // Better than using VLA
    char **names = malloc(x*sizeof(*names));
    if(!names) err("Error allocating names");

    printf("Enter the names:\n");
    for(i=0;i<x;i++) {
        if(!fgets(ch, 50, stdin)) err("Error reading line");
        ch[strcspn(ch, "\n")] = 0; // Remove newline
        if(!(names[i] = strdup(ch))) err("Error duplicating string");
    }

    for(int i=0; i<x; i++)
        printf("name %d: %s\n", i, names[i]);
}

Всякий раз, когда функция имеет возвращаемое значение, которое может указывать на ошибку, вы должны ВСЕГДА проверять ее, и здесь это относится к malloc, fgets, strdup и sscanf и. Прочтите документацию, чтобы узнать, что она на самом деле возвращает, и узнать, как проверять ошибки. sscanf возвращает количество успешных назначений, а остальные три возвращают указатель, который при ошибке равен NULL.

Вы написали в комментариях, что вы учитесь из книги «Позвольте нам C». Лучше всего подойдет заголовок «Как не кодировать С». Я быстро взглянул на это, и это действительно очень плохо. Помимо преподавания очень устаревшего языка С, он также учит очень вредным привычкам в целом. На самом деле, большинство вопросов о C можно отнести к этой книге, или, по крайней мере, могли бы иметь. Два основных примера - это то, что он последовательно избегает очень важных вещей, таких как функции проверки ошибок, такие как scanf и malloc. Я не читал каждую строку, но думаю, что в ней даже не упоминается, как проверять ошибки scanf даже один раз. Он также использует функцию gets, которая не только устарела, но и полностью удалена из новых стандартов C, поскольку она очень опасна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...