我有一个如下所示的代码,最后一条语句只有在我使用l_plates[I]时才有效。在下面的情况下,它抛出一个错误"传递'sprintf'的参数1使指针从整数不强制转换"如果我还需要N的另一个for循环呢?如果我使用sprint,我是否应该使用额外的元素?请解释一下。提前谢谢。
char type, letters[4], digits[5];
char l_plates[M][N];
for (i=0; i<M; i++) {
scanf(" %c", &type);
scanf("%3s", letters);
scanf("%4s", digits);
sprintf(l_plates[i][N], "%s %s %c", letters, digits, type);
}
我看到了两个问题。首先,sprintf的第一个参数应该是char*
,而不是char
,这是你发送给它的。
其次,将大小为N
的数组从0
索引到N - 1
。通过尝试访问元素N
,您将步出数组。最后一个元素是[N - 1]
在sprintf
行中,表达式l_plates[i][N]
指的是单个字符,而您试图将其写入整个字符串。
变量l_plates
是一个包含长度为N
的字符串的一维数组(或者是一个包含字符的二维数组)。
如果你需要一个二维字符串数组,那么你需要像这样定义l_plates
:
char* l_plates[M][N];
然后malloc相应的字符串
让我们看一下l_plates
:
char l_plates [M] [N]。
表示l_plates
是包含M
字符的N
数组的数组。另一种考虑方式是将其视为一个二维字符数组。
那么l_plates[i][N]
的类型是什么?这是char
!换句话说,它是一个单一的符号。然而,sprintf()
需要char*
作为它的第一个参数。这就是为什么上面的代码会出现编译错误。
l_plates[i]
是char
s的数组。C和c++都可以将此数组转换为char*
,因此编译器不会报错。
这是因为l_plates[i]
是一个字符串,而l_plates[i][N]
是一个字符,尽管是一个超出边界的字符(因为N-1
是最后一个字符)。
也就是说,您最好使用snprintf()
:
snprintf(l_plates[i], N, "%s %s %c", letters, digits, type);
你应该看看c语言中指针和数组是如何工作的。
l_plates[i][N]
实际上指的是char
,所以它甚至不会编译;sprintf期望将char*
写入输出。l_plates[i]
的类型为char[N]
,可隐式转换为char*
,指向内部数组的开头。把这个作为参数给sprint,它就会做你想做的事情。
l_plates[i][N]
时,您是在非法偏移处访问内部数组。大小为N的数组的偏移量应该在0到N-1之间。C/c++在运行时不一定会抱怨这个问题,但它几乎总是一个bug。在这种情况下,l_plates[M-1][N]
指向分配给l_plates
的内存之外。