Пишу свою первую программу на C, и я не могу преодолеть эту глупую ошибку - PullRequest
2 голосов
/ 01 мая 2011

Я использую xCode, потому что нашел отладчик очень полезным.Итак, в отладчике я вижу, что после ввода имени ученика имя [0] = \ 0, что бы ниНо тогда остальное имя будет правильным.Например, если я поставлю Джона, он вернется со словами \ 0, o, h, n.Помогите пожалуйста?

        char name[MAX_NAME_LENGTH];
        char department[MAX_DEPT_LENGTH];
        int rank;
        int empty = 0;

        printf("\nPlease enter the students name: ");
        scanf("%s", &name);
        printf("\nPlease enter the students department: ");
        scanf("%s", &department);
        printf("\nPlease enter the students rank: ");
        scanf("%d", &rank);


        strcpy(studentArray[empty].name, name);
        strcpy(studentArray[empty].department, department);
        studentArray[empty].rank = rank;

Ответы [ 6 ]

2 голосов
/ 01 мая 2011

Сделайте это:

    printf("\nPlease enter the students name: ");
    scanf("%s", name);
    printf("\nPlease enter the students department: ");
    scanf("%s", department);
    printf("\nPlease enter the students rank: ");
    scanf("%d", &rank);

Обратите внимание на отсутствие амперсандов в первых двух вызовах scanf. Это связано с тем, что компилятор неявно преобразует name и department в указатели на первые элементы соответствующих массивов (&name[0], &department[0]), когда они используются в выражении (есть исключения для этого правила, см. здесь для деталей).

Прочитайте это для дальнейшего использования.

1 голос
/ 01 мая 2011

Вам нужно использовать scanf("%s", name); вместо scanf("%s", &name); (то же самое для department).

scanf нужен адрес памяти для записи.В случае строки она ожидает char *, и передача char[] вполне подходит в этом случае (хотя она уязвима для переполнения буфера! ).

Однако для вашего целого- который не является указателем - вам нужно передать адрес памяти целого числа, то есть &rank вместо rank - что вы уже сделали.

0 голосов
/ 01 мая 2011

Когда вы объявляете массив,

    char name[MAX_NAME_LENGTH];

name без индекса является указателем на первый элемент в массиве.

name == &name[0]

Когда функция (например, scanf()) вызывает char *, она хочет указатель на первый элемент.

scanf("%s", name);
0 голосов
/ 01 мая 2011

Функция scanf должна знать адрес в памяти, в котором она должна считываться, поэтому для таких вещей, как целые числа

scanf("%d", &rank);

правильно. Но такие вещи, как имя, уже являются адресами (имя массива фактически является адресом его первого элемента), поэтому вместо:

scanf("%s", &name);

Вы хотите:

scanf("%s", name);

И аналогично для других массивов.

0 голосов
/ 01 мая 2011

Ваши переменные name и department являются символьными массивами (char (*)[]).Когда вы передаете эти переменные в printf / scanf (или любую другую функцию, массивы передаются по ссылке), их типы уменьшаются до TYPE* (в вашем случае char*) и передаются как ячейка памяти первого элемента вмассив.

Когда вы пытаетесь передать адрес переменной (&name), вы передаете указатель на ячейку памяти этой переменной (в вашем случае это значение уменьшается до char(*)[0]).Этот вопрос меня заинтриговал, потому что name и &name будут иметь одинаковое значение, но разных типов.Поскольку printf / scanf определены для получения char*, передача char (*) [] приводит к неопределенному поведению - некоторые компиляторы будут обрабатывать, если за вас, а другие - нет (VS2010 и, возможно, более ранние версии обрабатывают это для вас).*

Я был близок, но помог мне с этим ответом (многому научился): & определение оператора для массивов в C .Если они ответят здесь, я удалю мой.

0 голосов
/ 01 мая 2011

использование scanf("%s", name);

избегайте использования &, слишком легко ошибиться.

...