user2247287
user2247287

Reputation: 37

why should we not include the last array element in sprintf?

I have a code shown as below, the last statement works only if I use l_plates[i]. In the below case it throws an error "passing argument 1 of 'sprintf' makes pointer from integer without a cast" What if I need another for loop for N too. Should I use an extra element if I use sprintf? please explain. thanks in advance.

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);
}

Upvotes: 1

Views: 714

Answers (5)

yonil
yonil

Reputation: 574

You should look up about how pointers and arrays work in C.

l_plates[i][N] actually refers to a char, so it won't even compile; sprintf expects a char* to where it will write the output. l_plates[i] has type char[N], implicitly convertible to char*, pointing to the beginning of the inner array. Giving that as argument to sprintf makes it do what you probably want.

By the way, with l_plates[i][N] you're accessing the inner array at an illegal offset. The offset to a size N array should be between 0 to N-1. C/C++ will not necessarily complain about this at runtime, but it's almost always a bug. In this case l_plates[M-1][N] does point outside the memory allocated for l_plates.

Upvotes: 0

Ja͢ck
Ja͢ck

Reputation: 173662

That's because l_plates[i] is a string whereas l_plates[i][N] is a single character, albeit an out-of-bound one (because N-1 is the last character).

That said, you might be better off with snprintf():

snprintf(l_plates[i], N, "%s %s %c", letters, digits, type);

This makes sure you don't overflow your character array.

Upvotes: 0

Code-Apprentice
Code-Apprentice

Reputation: 83607

Let's look at the declaration of l_plates:

char l_plates[M][N];

This says that l_plates is an array of N arrays of M characters. Another way to think of this is as a two-dimensional array of characters.

So what is the type of l_plates[i][N]? It's a char! In other words, it is a single symbol. However, sprintf() requires a char* as its first argument. This is why you get a compiler error with your above code.

On the other hand l_plates[i] is an array of chars. C and C++ can both convert this array to a char*, so the compiler won't complain.

Upvotes: 0

Parker Kemp
Parker Kemp

Reputation: 765

I see two problems here. First, the first argument of sprintf should be a char*, not a char, which is what you're sending to it.

Secondly, an array of size N is indexed from 0 to N - 1. By trying to access element N, you're stepping outside of the array. The last element is [N - 1].

Upvotes: 4

Nicol&#225;s Ozimica
Nicol&#225;s Ozimica

Reputation: 9768

In your sprintf line, the expression l_plates[i][N] refers to a single char, and you're trying to write to it a whole string.

The variable l_plates is a one dimensional array of strings of length N (or a two dimensional array of chars).

If you need a two dimensional array of strings, then you need to define l_plates with something like this:

char* l_plates[M][N];

and then malloc those strings accordingly.

Upvotes: 0

Related Questions