简体   繁体   中英

Initializing a char with an int in C

I am new to C programming and would like to create a char that puts text before an int.

char charPin[] = ("PIN%d",pin);

I want it so I can pass charPin to an external function. I am receiving an invalid initializer on the beginning of the line.

You need a constant initialiser for incomplete arrays, so the compiler can determine the size at run-time. So it is not easily possible to use a variable for the pin-number.

If you can live with a constant pin, the following works:

#define STRINGIZE(x)    #x
#define CONCAT(a,b)     STRINGIZE(a##b)

static const char p10[] = CONCAT(PIN, 10);

int main(void)
{
    printf("%s\n", p10);
    return 0;
}

The # yields the argument enclosed with quotation marks, the concatenation operator ## concatenates the two arguments to a single one. They are preprocessor operators, which is the reason this does not work with variables.

A more useful example woud be to parametrize the pin-number only and use a macro to generate the rest of the text:

#define PIN(n)   STRINGIZE(PIN, n)

// usage:
... PIN(10) ...

That way you can change the text with just changing a single macro definition, eg for a different language:

#define PIN(n)   STRINGIZE(Anschluss, n)

If you need a variable, you have to put some more effort into it. However, if that is an example for the text you want to get, it might be easier to generate the names on-the fly along with the rest of the text you want to output, instead of storing into some array.

The best code depends on context you did not provide.

Your statement

 char charPin[] = ("PIN%d",pin); 

is attempting to initialize an unspecified-length array of char with the expression ("PIN%d",pin) . That expression looks Pythonesque, but it is syntactically valid in C: the parentheses perform their ordinary grouping function around an expression involving the comma ( , ) operator. Evaluated in a context that actually allows that expression, the result would have the same type and value as pin . That's not at all what you intend, and luckily the problem is of a type that the compiler rejects, as opposed to the one for which the compiler generates code to do the unintended thing you actually told it to do.

The initializer for an array of char can take either of two forms:

  • a string or UTF-8 literal, or
  • a brace-enclosed array of individual elements.

Neither of those suits your purpose, so you'll have to fill the array with your desired contents separately from its declaration. Moreover, that means you'll have to declare an explicit size for your array. You need space for the text part (whose size you know), for the integer part (whose size is variable, within limits), and for a one-byte string terminator.

If you're willing to make the very reasonable assumption that pin 's data type ( int ?) is no wider than 64 bits, then 20 characters will be sufficient for the maximum possible 19 decimal digits plus a sign, therefore 24 characters should be enough for the whole string. It's usually best to avoid magic numbers in your code, so you might declare charPin like so:

#define PIN_BUFFER_SIZE 24

// ...

char charPin[PIN_BUFFER_SIZE];

There are several ways you could fill set the array contents, but the most straightforward way for your case would be to use either sprintf() or snprintf() . Suppose we're not entirely confident in our size computation, or that the text part is variable. We might then declare a bit more space in charPin than we think we'll need, but ultimately we want to ensure that we do not overwrite the bounds of the array. snprintf() is intended for that purpose:

int result = snprintf(charPin, PIN_BUFFER_SIZE, "PIN%d", pin);

That's the basic answer, but a careful programmer would not leave it at that. Supposing we want to be alerted in the event that our assumption about the needed space was wrong, instead of just letting the data be truncated, we would want to test the function's return value and handle any error that it indicates. We would also want to check for a general error code, as generally we should do for every function call that can signal an error:

if (result >= PIN_BUFFER_SIZE) {
    fprintf(stderr, "PIN truncated\n");
    exit(EXIT_FAILURE);  // or handle it some less-drastic way
} else if (result < 0) {
    // should not happen, but we're being thorough
    fprintf(stderr, "Internal I/O error\n");
    exit(EXIT_FAILURE);  // or handle it some less-drastic way
}

What you are looking for is the sprintf function. First you have to declare an array big enough to store the result ( which might not be easy , so in my example I'm using a fixed size of 50 characters), then using the function you initialize it with formatted data. You don't have to check the resulting string's length with strlen , because sprintf returns it already.

size_t arraySize = 50;
char charPin[arraySize];
int resultSize = sprintf(charPin, "PIN%d", pin);

If sprintf failed, resultSize will be a negative value. You can handle it with

if (resultSize < 0) {
    // react to failure here
}

Now to print the result you can use printf("%s", charPin); .

If you are trying to initialize the char array with a constant value, you can just write the PIN number (52 in my example) inside a string literal.

char charPin[] = "PIN52";

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM