多维c数组的问题

时间:2010-11-11 15:44:20

标签: c

好的我是编程的新手,所以对我很轻松。我想制作一个程序,允许用户输入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 个答案:

答案 0 :(得分:2)

一些事情:

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个字符。但是你将它视为一个30x4的字符串数组。有些东西没有加起来。请考虑使用此代码:

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

是的,指点多维数组就好了。数组变量实际上只是指针,所以它实际上只是指针数学。

答案 1 :(得分:1)

但是,我认为现在的代码已经破了。

有一个包含30个元素的数组,其中每个元素都是40个字符。

然后代码循环遍历30个元素中的每一个;对于每个元素,它然后遍历前四个字符,将字符串(“%s”)扫描到每个字符中。第二个scanf将覆盖除第一个scanf的第一个char之外的所有char,第三个scanf将覆盖除第一个和第二个scanf的第一个char之外的所有char,等等。

答案 2 :(得分:0)

你想要一个结构。

一个结构可以容纳几种不同的类型(char []用于学生姓名; enum MaritalStatus用于婚姻状况; enum性别用于性别;等等......)在一个对象中,例如

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];
    /* ... */
};

答案 3 :(得分:0)

几个问题:

首先,您已将std定义为包含char的40个元素数组的30个元素数组; IOW,你最多可以存储30个字符串,最多39个字符(加0个终结符),而不是120个字符串。

其次,要读入每个字符串,对scanf的调用只是

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

表达式 std[x]的类型是char [40],或者是40个元素的char数组。但是,有一个规则,当遇到类型为“N-element of T”的表达式时,它们被隐式转换(“衰减”)到类型“指向T的指针”(此规则的例外是当数组表达式为sizeof或一元&运算符的操作数,或者数组表达式是否用于初始化声明中的另一个数组的字符串文字);因此,在此上下文中,表达式std[x]的类型衰减为类型char *或指向char的指针,因此您无需显式使用&运算符。

使用scanf这样的风险是,用户可以键入比目标缓冲区更多的字符;如果用户键入100个字符,那么额外的60个字符将在紧接缓冲区末尾的存储器中存储,这可能会或可能不会在以后引起问题。您可以通过以下两种方式解决这个问题:首先,您可以为%s转换规范添加字段宽度说明符,如下所示:

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

第二,您可以完全避免使用scanf并改为使用fgets

fgets(std[x], sizeof std[x], stdin);