Arrays Can';t通过scanf()指定可变长度数组大小
我正在尝试使用scanf()获取用户输入以获取数组大小。共有2个数组,scanf()要求输入2个由空格分隔的数字。第一个数组的大小永远无法分配,但第二个数组没有任何问题 这是代码,下面是我正在使用的环境Arrays Can';t通过scanf()指定可变长度数组大小,arrays,c,debugging,scanf,Arrays,C,Debugging,Scanf,我正在尝试使用scanf()获取用户输入以获取数组大小。共有2个数组,scanf()要求输入2个由空格分隔的数字。第一个数组的大小永远无法分配,但第二个数组没有任何问题 这是代码,下面是我正在使用的环境 int main(无效) { uint32_t numelarr1=0,numelarr2=0; printf(“输入数组-1和数组-2中由空格分隔的元素数:”); scanf(“%d%d”、&numelarr1和&numelarr2); int32_t arr1[numelarr1]; int
int main(无效)
{
uint32_t numelarr1=0,numelarr2=0;
printf(“输入数组-1和数组-2中由空格分隔的元素数:”);
scanf(“%d%d”、&numelarr1和&numelarr2);
int32_t arr1[numelarr1];
int32_t arr2[numelarr2];
}
numEleArr1将不会分配给arr1!为什么?
请注意,我使用外部控制台允许用户输入,但这不会影响程序,因为即使没有它,我仍然会出错
对不起,我忘了圈出有问题的变量。但是您可以查看下面屏幕截图左侧的变量,arr1
的值未知?
但是arr2
的值已成功输入
环境:
- Mac OS BigSur(英特尔)
- VS代码
#包括
#包括
#包括
/*清空stdin的简单函数*/
void empty\u stdin(void)
{
int c=getchar();
而(c!='\n'&&c!=EOF)/'\n'=ASCII(10)=换行或换行返回或换行
c=getchar();
}
无效交换阵列(int32阵列1、uint32阵列2、uint32阵列2、uint32阵列2、uint32阵列2);
无效打印阵列(int32*pArray,uint32元素);
内部主(空)
{
uint32_t numelarr1=0,numelarr2=0;
for(;;){/*持续循环,直到提供有效输入*/
int rtn;/*返回scanf*/
fputs(“\n输入数组中的元素数-1”
和数组-2,由空格分隔:,stdout);
fflush(stdout);
/*读取值,保存返回,注意精确宽度类型的正确语法*/
rtn=scanf(“%”SCNu32“%”SCNu32、&numEleArr1、&numEleArr2);
如果(rtn==EOF){/*用户用ctrl+d(windows上的ctrl+z)取消*/
puts(“(用户取消输入)”);
返回0;
}
empty_stdin();/*empty stdin*/
如果(rtn!=2)/*匹配失败*/
fputs(“错误:无效的uint32_t输入。\n”,stderr);
其他的
中断;/*良好输入,中断读取循环*/
}
int32_t arr1[numelarr1];/*声明VLAs*/./存在许多微妙的问题,其中最重要的问题是未能为scanf()
和printf()
使用正确的精确宽度格式说明符(在inttypes.h
中提供)。此外,您正在尝试使用有符号的%d
转换说明符读取无符号值
此外,您无法知道您的输入是成功还是失败,因为您无法从scanf()
检查返回值(除非检查返回值,否则无法正确使用任何输入函数)
为精确宽度类型的输入和输出提供正确的宏。使用scanf()
时,正确的转换说明符是SCN{fmt}{type}
,其中fmt
是d
(十进制)、x
(十六进制)、o
(八进制)、u
(无符号)和i
(整数)之一.type
是N
、FASTN
、LEASTN
、PTR
、MAX
中的一种,其中N
对应于参数中的位数。printf()
的格式说明符类似于PRI
(注意,宏必须不在双引号内才能正确展开)
再加上一个输入例程,要求用户输入两个有效的uint32_t
值,或者用Ctrl+d(windows上的Ctrl+z)取消输入。如果用户输入了无效的uint32_t
值,如“foo”
,您必须在下次尝试之前清空stdin
,否则相同的字符将保留在stdin
中,导致完全相同的故障(下面使用了一个简单的函数)
总之,你可以做类似的事情:
#包括
#包括
/*清空stdin的简单函数*/
void empty\u stdin(void)
{
int c=getchar();
而(c!='\n'&&c!=EOF)
c=getchar();
}
内部主(空)
{
uint32_t numelarr1=0,numelarr2=0;
for(;;){/*持续循环,直到提供有效输入*/
int rtn;/*返回scanf*/
fputs(“\n输入数组中的元素数-1”
和数组-2,由空格分隔:,stdout);
/*读取值,保存返回,注意精确宽度类型的正确语法*/
rtn=scanf(“%”SCNu32“%”SCNu32、&numEleArr1、&numEleArr2);
如果(rtn==EOF){/*用户用ctrl+d(windows上的ctrl+z)取消*/
puts(“(用户取消输入)”);
返回0;
}
empty_stdin();/*empty stdin*/
如果(rtn!=2)/*匹配失败*/
fputs(“错误:无效的uint32_t输入。\n”,stderr);
其他的
中断;/*良好输入,中断读取循环*/
}
int32_t arr1[numelarr1];/*声明VLA*/
int32_t arr2[numelarr2];
/*输出数组大小*/
printf(“arr1[%“PRIu32”]arr2[%“PRIu32”]\n”,numelarr1,numelarr2);
(无效)arr1,(无效)arr2;/*为避免出现错误,将其转换为(无效)-未使用警告*/
}
numelarr1
和numelarr2
的值是显示结果的输出。对(void)
的强制转换只需避免未使用arr1
和arr2
的编译器警告
示例使用/输出
Enter the number of elements in Array-1 and Array-2 separated by a space: 3 4
arr1[3] arr2[4]
Enter the Array-1 element's number 1: 1
Enter the Array-1 element's number 2: 2
Enter the Array-1 element's number 3: 3
Enter the Array-2 element's number 1: 9
Enter the Array-2 element's number 2: 8
Enter the Array-2 element's number 3: 7
Enter the Array-2 element's number 4: 6
Array-1 elements before swap are: 1 2 3
Array-2 elements before swap are: 9 8 7 6
Arrays contents after swapping:
Array-1 elements after swap are: 9 8 7
Array-2 elements after swap are: 1 2 3 1
Press any key to exit program . . .