为什么不能在sprintf中包含最后一个数组元素?



我有一个如下所示的代码,最后一条语句只有在我使用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的内存之外。

最新更新