Проблема с многомерным массивом c - PullRequest
0 голосов
/ 11 ноября 2010

Хорошо, я новичок в программировании, так что будь осторожен со мной. Я хочу сделать программу, которая позволяет пользователю вводить имя, семейное положение, пол и место жительства 30 студентов. Вот мой код, и единственная проблема в том, что программа допускает входы выше ожидаемых 120 входов.

#include <stdio.h>

char std[30][40];
int x,y;

main()
{
  printf("Enter number of students: \n");

  for(x=0;x<30;x++)
    for(y=0;y<4;y++)
      scanf("%s" &std[x][y],);

  return 0;
}

Мне интересно: могу ли я использовать указатели для доступа к элементам многомерного массива?

Ответы [ 4 ]

2 голосов
/ 11 ноября 2010

Несколько вещей:

for(x=o;x<30;x++)

Конечно, вы имели в виду 0, а не o там. Кто знает, что содержит o, но, видимо, не ноль ...

Это:

char std[30][40];

И это (исправлено):

for(x=0;x<30;x++)
  for(y=0;y<4;y++)
    scanf("%s", &std[x][y]);

Не совпадают. Вы объявляете std по сути как массив из 30 строк, каждая длиной 40 символов. Но вы рассматриваете это как массив строк 30х4. Что-то не складывается. Попробуйте использовать это вместо:

for(x=0;x<30;x++)
  scanf(" %s", &std[x][0]);

И да, брать указатели на многомерные массивы - это нормально. В любом случае переменные массива на самом деле просто указатели, так что на самом деле это просто математика указателей.

1 голос
/ 11 ноября 2010

Да.

Тем не менее, я думаю, что код там сейчас не работает.

Существует массив из 30 элементов, каждый элемент которого составляет 40 символов.

код затем перебирает каждый из 30 элементов;для каждого элемента он проходит по первым четырем символам, просматривая строку ("% s") в каждом символе.Второй scanf будет перезаписывать все, кроме первого символа первого scanf, третий scanf будет перезаписывать все, кроме первого символа первого и второго scanf и т. Д.

0 голосов
/ 11 ноября 2010

Несколько выпусков:

Прежде всего, вы определили std как 30-элементный массив из 40-элементных массивов char; Таким образом, вы можете хранить не более 30 строк не более 39 символов (плюс 0-терминатор), а не 120 строк.

Во-вторых, чтобы прочитать каждую из этих строк, вызов scanf будет просто

for (x = 0; x < 30; x++)
  scanf("%s", std[x]);

Типом выражения std[x] является char [40], или массив из 40 элементов char. Однако существует правило, согласно которому при обнаружении выражений типа «N-элемент T» они неявно преобразуются («распад») в тип «указатель на T» (исключения из этого правила возникают, когда выражение массива является операнд sizeof или унарные & операторы, или если выражение массива является строковым литералом, используемым для инициализации другого массива в объявлении); таким образом, в этом контексте тип выражения std[x] распадается на тип char * или указатель на char, поэтому вам не нужно явно использовать оператор &.

Риск использования scanf подобным образом заключается в том, что пользователь может ввести больше символов, чем может вместить целевой буфер; если пользователь вводит 100 символов, эти дополнительные 60 символов будут сохранены в памяти сразу после конца буфера, что может вызвать или не вызвать проблемы в дальнейшем. Вы можете обойти это двумя способами: во-первых, вы можете добавить спецификатор ширины поля в спецификацию преобразования %s, например:

scanf("%39s", std[x]);

секунду, вы можете полностью не использовать scanf и использовать fgets вместо:

fgets(std[x], sizeof std[x], stdin);
0 голосов
/ 11 ноября 2010

Вы хотите структуру.

Структура может содержать несколько различных типов (char [] для имен учащихся; enum MaritalStatus для семейного положения; enum Gender для секса; и т. Д. ...) в одном объекте, например

enum MaritalStatus { MS_SINGLE, MS_MARRIED, MS_DIVORCED,
                     MS_WIDOWED, MS_UNKNOWN, MS_OTHER };
enum Gender { G_MALE, G_FEMALE, G_UNDECIDED, G_UNKNOWN, G_OTHER };
struct Student {
    char name[120];
    enum MaritalStatus maritalstatus;
    enum Gender gender;
    char residence[120];
    /* ... */
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...