简体   繁体   中英

Appending a char w/ null terminator in C

perhaps a lil trivial, but im just learning C and i hate doing with 2 lines, what can be done with one(as long as it does not confuse the code of course).

anyway, im building strings by appending one character at a time. im doing this by keeping track of the char index of the string being built, as well as the input file string's(line) index.

str[strIndex] = inStr[index];
str[strIndex + 1] = '\0';

str is used to temporarily store one of the words from the input line. i need to append the terminator every time i add a char.

i guess what i want to know; is there a way to combine these in one statement, without using strcat()(or clearing str with memset() every time i start a new word) or creating other variables?

Simple solution: Zero out the string before you add anything to it. The NUL s will already be at every location ahead of time.

// On the stack:
char str[STRLEN] = {0};

// On the heap
char *str = calloc(STRLEN, sizeof(*str));

In the calloc case, for large allocations, you won't even pay the cost of zeroing the memory explicitly (in bulk allocation mode, it requests memory directly from the OS, which is either lazily zero-ed (Linux) or has been background zero-ed before you ask for it (Windows)).

Obviously, you can avoid even this amount of work by defering the NUL termination of the string until you're done building it, but if you might need to use it as a C-style string at any time, guaranteeing it's always NUL -terminated up front isn't unreasonable.

Declare a char array:

char str[100];

or,

char * str = (char *)malloc(100 * sizeof(char));

Add all the character one by one in a loop:

for(i = 0; i<length; i++){
    str[i] = inStr[index];
}

Finish it with a null character (outside the loop):

str[i] = '\0';

I believe the way you are doing it now is the neatest that satisfies your requirement of

1) Not having string all zero to start with

2) At every stage the string is valid (as in always has a termination).

Basically you want to add two bytes each time. And really the most neat way to do that is the way you are doing it now.

If you are wanting to make the code seem neater by having the "one line" but not calling a function then perhaps a macro:

#define SetCharAndNull( String, Index, Character )  \
{                                                   \
    String[Index] = (Character);                    \
    String[Index+1] = 0;                            \
}

And use it like:

SetCharAndNull( str, strIndex, inStr[index]);

Otherwise the only other thing I can think of which would achieve the result is to write a "word" at a time (two bytes, so an unsigned short ) in most cases. You could do this with some horrible typecasting and pointer arithmetic. I would strongly recommend against this though as it won't be very readable, also it won't be very portable. It would have to be written for a particular endianness, also it would have problems on systems that require alignment on word access.

[Edit: Added the following] Just for completeness I'm putting that awful solution I mentioned here:

*((unsigned short*)&str[strIndex]) = (unsigned short)(inStr[index]);

This is type casting the pointer of str[strIndex] to an unsigned short which on my system (OSX) is 16 bits (two bytes). It is then setting the value to a 16 bit version of inStr[index] where the top 8 bits are zero. Because my system is little endian, then the first byte will contain the least significant one (which is the character), and the second byte will be the zero from the top of the word. But as I said, don't do this! It won't work on big endian systems (you would have to add in a left shift by 8), also this will cause alignment problems on some processors where you can not access a 16bit value on a non 16-bit aligned address (this will be setting address with 8bit alignment)

First of all, C doesn't have strings, only arrays of char. Therefore, you would have to assign each character one by one like you are doing if you don't want to use other auxiliary functions. But the \\0 character goes only in the end of an array of char.

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