我已经定义了一个指向结构的指针数组,当我尝试扫描到一个字段时,我收到一条错误消息,我无法理解我做错了什么。
我尝试了不同的方法 - scanf("%s",arr[i]->code);
或scanf("%s",(*(arr+i))->code);
- 它仍然无效。
这是我的代码的开头:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#define N 5
typedef struct DEPARTMENT
{
char code[11];
int sales;
}
department;
int main()
{
department *arr[N];
int i;
printf("Enter values for %d departments:", N);
for (i = 0; i < N; i++)
{
printf("\nThe %d department-", (i + 1));
printf("\nCode:");
scanf("%s",(arr[i])->code);
printf("\nNumber of sales:");
scanf("%d", &((arr[i])->sales));
}
}
你确实声明了你的qazxsw poi数组,你没有分配每个qazxsw poi的记忆。
您可以在循环中执行此操作,在此处填充数组:
department
如评论中提到的更清洁的解决方案,一个分配就足够了:
department
别忘了释放分配的内存并检查for (i = 0; i < N; i++)
{
arr[i] = malloc(sizeof(department));
/* .. */
}
s的返回值。
您当前的问题是尝试将值分配给无效的内存位置。你的声明:
department *arr = malloc(sizeof(department) * N);
声明一个指向struct DEPARTMENT [N]的指针数组(例如指向struct的5个指针)。但是,每个指针都是未初始化的,并指向不确定的内存位置。请记住,指针只是一个普通变量,它将其他东西的地址保存为其值,就像普通变量一样,它保持一个不确定的值,直到分配一个。
就像声明的任何其他局部变量一样,在值不确定时访问该值的任何尝试都会导致未定义的行为。要使用指针数组,必须将每个指针的起始地址分配给有效的内存块作为其值。在这里,由于您的目的是为malloc
结构提供存储,因此无需声明 department *arr[N];
指针,然后独立地为N
结构分配存储空间。您可以简单地声明一个指向struct的指针,然后在单个内存块中为N
struct分配存储空间,例如:
N
(注意:始终验证每个分配)
在单个块中为N
结构分配存储具有提供单个#define N 5
...
typedef struct {
char code[MAXC];
int sales;
} department;
...
department *arr; /* declares a pointer to struct */
...
/* allocate/validate storage for N struct */
if ((arr = malloc (N * sizeof *arr)) == NULL) {
perror ("malloc-arr");
return 1;
}
来释放分配的内存块的优点。
正如您必须验证每个分配一样,您必须验证每个用户输入。这意味着至少,您必须验证每个所有人返回N
的回报。但是,你使用free()
有一个缺点。输入scanf
是非常脆弱的,因为输入的任何变化都会导致匹配失败,scanf
中的字符提取将在匹配失败发生时停止,使得scanf
中的违规字符未读,只是等待你在下次调用stdin
时再次咬你。此外,如果有任何跟随有效输入的无意字符,它们也会保持在未读的stdin
中。
您的选择是在每次输入后清空scanf
以确保没有任何违规字符,或者,更好的选择是每次使用stdin
或POSIX stdin
等面向行的输入函数读取完整的输入行,然后解析您需要的值从填充的缓冲区。这有很多好处。每个输入都会读取和丢弃任何无关的字符。您还可以独立验证(1)读取; (2)从缓冲区中解析所需信息。您可以使用fgets()
来解析填充缓冲区中的信息,就像使用getline()
从sscanf
读取一样。
完全放在那里,您可以重写您的代码,如下所示:
scanf
(注意:使用单独的索引计数器stdin
,它提供了即使用户在输入后取消输入也填充的实际结构数的计数,例如3个部门而不是5个)
示例使用/输出
#include <stdio.h>
#include <stdlib.h>
#define N 5
#define CODESZ 12 /* if you need more than 1 constant, define them */
#define MAXC 1024 /* (don't skimp on buffer size) */
typedef struct {
char code[MAXC];
int sales;
} department;
int main()
{
department *arr; /* declares a pointer to struct */
char buf[MAXC]; /* buffer to hold each line */
int i, ndx = 0;
/* allocate/validate storage for N struct */
if ((arr = malloc (N * sizeof *arr)) == NULL) {
perror ("malloc-arr");
return 1;
}
printf("Enter values for %d departments:\n", N);
while (ndx < N) { /* loop until info for N departments received */
printf ("\nThe %d department-\n Code : ", ndx + 1);
if (fgets (buf, MAXC, stdin) == NULL ||
sscanf (buf, "%11s", arr[ndx].code) != 1)
break;
fputs (" Sales : ", stdout);
if (fgets (buf, MAXC, stdin) == NULL ||
sscanf (buf, "%d", &arr[ndx].sales) != 1)
break;
ndx++;
}
puts ("\nDepartment Sales Results:\n");
for (i = 0; i < ndx; i++) /* output results, free memory */
printf ("Dept Code: %-12s Sales: %d\n", arr[i].code, arr[i].sales);
free (arr); /* don't forget to free what you allocate */
}
输入后尝试输入附加文本(甚至还有一个额外的击键)并查看代码的响应方式。保持Ctrl + C准备就绪。
仔细看看,如果您有其他问题,请告诉我。