C line questions

I am new to C and am very confused about C-lines. Below are my questions.

Search for the last character from a string

How to find out the last character from a string? I came up with something like:

char *str = "hello"; printf("%c", str[strlen(str) - 1]); return 0; 

Is that the way? I somehow think this is not the right way because strlen has to strlen over the characters to get the length. So this operation will have O(n) complexity.

Convert char to char*

I have a string and you need to add char to it. How can i do this? strcat accepts only char* . I tried the following:

 char delimiter = ','; char text[6]; strcpy(text, "hello"); strcat(text, delimiter); 

Using strcat with local scope variables

Please consider the following code,

 void foo(char *output) { char *delimiter = ','; strcpy(output, "hello"); strcat(output, delimiter); } 

In the above code, delimiter is a local variable that is destroyed after foo returns. Is it possible to add it to the output variable?

How does strcat handle a null terminating character?

If I concatenate two null-terminated strings, will strcat add two null-returning characters to the resulting string?

Is there a good beginner-level article that explains how strings work in C and how can I do regular string manipulations?

Any help would be great!

+6
c string
source share
7 answers
  • Last character: your approach is correct. If you need to do this a lot on large strings, your data structure containing strings should store lengths with them. If not, then it does not matter that it is O (n).

  • Adding a character: you have a few errors. On the one hand, your buffer is too small to hold another character. As for calling strcat, you can either put the character in a string (an array with 2 entries, the second 0), or you can simply manually use the length to write the character to the end.

  • Your concern for 2 nul terminators is unfounded. While it takes up memory associated with the string and is needed, the zero byte at the end is NOT a "part of the string" in terms of length, etc. This is a pure marker of the end. strcat will overwrite the old nul and add a new one at the very end after the concatenated string. Again, you need to make sure your buffer is big enough before you call strcat!

+7
source share
  • O (n) is the best you can do, due to the way C strings work.
  • char delimiter[] = ","; . This makes the delimiter a character array containing a comma and NUL. In addition, the text should have a length of 7. Hi 5, then you have a comma and NUL.
  • If you correctly define the separator, this thin one (as is, you assign a character to a pointer, which is wrong). The contents of the output will not depend on the delimiter in the future.
  • It will overwrite the first NUL.

You are on the right track. I highly recommend you read the K & RC 2nd Edition. This will help you with strings, pointers, etc. And don't forget the man pages and documentation. They will clearly answer questions such as strcat . Two good sites are The Open Group and cplusplus.com.

+5
source share

"String C" is actually a simple char s array, with str[0] containing the first character, str[1] second, etc. After the last character, the array contains another element that contains zero. This zero by convention marks the end of the line. For example, these two lines are equivalent:

 char str[] = "foo"; //str is 4 bytes char str[] = {'f', 'o', 'o', 0}; 

And now for your questions:

Search for the last character from a string

Your path is right. There is no faster way to find out where a line ends than scanning through it to find the final zero.

Convert char to char *

As said earlier, a β€œstring” is just an array of char s with the addition of a null terminator to the end. Therefore, if you need a string of one character, you declare an array of two char - your character and trailing zero, for example:

 char str[2]; str[0] = ','; str[1] = 0; 

Or simply:

 char str[2] = {',', 0}; 

Using strcat with local scope variables

strcat() simply copies the contents of the source array to the destination array with a zero offset in the destination array. Therefore, it does not matter what happens to the source after the operation. But you DO need to worry if the destination array is large enough to store data, otherwise strcat() overwrite all the data in memory immediately after the array! The required size is strlen(str1) + strlen(str2) + 1 .

How does strcat handle a null terminating character?

A trailing zero is expected to complete both input lines and be added to the output line.

+3
source share

Search for the last character from a string

I suggest a thought experiment: if at all you could find the last character of a line better than O (n), then could you also implement strlen better than O (n) time?

Convert char to char*

You can temporarily store char in a char array, and this will fade out the-to- char pointer:

 char delimiterBuf[2] = ""; delimiterBuf[0] = delimiter; ... strcat(text, delimiterBuf); 

If you just use character literals, you can just use string literals.

Using strcat with local scope variables

The variable itself is not specified out of scope. When the function returns, the local variable has already been evaluated and its contents have already been copied.

How does strcat handle a null terminating character?

"Strings" in C is a sequence of characters with the character NUL. Both entries in strcat must be NUL-terminated, and the result will be NUL-terminated. It would not be useful for strcat to write an extra NUL byte to the result if it is not required.

(And if you're curious that if the input lines have several trailing NUL bytes already, I suggest another thought experiment: how would strcat know how many trailing NUL bytes are in the string?)

By the way, since you noted this with β€œbest practices,” I also recommend that you take care not to write over the end of the target buffers. This usually means that you avoid strcat and strcpy (unless you have already verified that the input lines will not overflow with the addressee) and the use of safer versions (e.g. strncat ). Please note that strncpy has its own errors, so this is a bad replacement. There are also safer, non-standard versions, such as strlcpy / strlcat and strcpy_s / strcat_s .)

Likewise, functions like your foo function should always have an additional argument specifying the size of the destination buffer (and the documentation should explicitly indicate whether the NUL terminator takes that size into account or not).

+1
source share

How to find out the last character from a string?

Your technique with str[strlen(str) - 1] wonderful. As indicated, you should avoid repeated unnecessary calls to strlen and save the results.

I somehow think that this is not the right way, because strlen must iterate over the characters to get the length. So this operation will have O (n).

Repeated calls to strlen may be a C program error. However, you should avoid premature optimization. If the profiler actually demonstrates an access point where strlen is expensive, then you can do something similar for your literal string example:

 const char test[] = "foo"; sizeof test // 4 

Of course, if you create a "test" on the stack, it carries little overhead (increasing / decreasing the stack pointer), but linear time is not involved.

Literal lines, as a rule, will not be so gigantic. For other cases, such as reading a large line from a file, you can save the line length in advance, as one example, to avoid recalculating the line length. It can also be useful as it will tell you in advance how much memory is allocated for your character buffer.

I have a string and you need to add char to it. How can i do this? strcat accepts only char *.

If you have a char and cannot output a string from it (char * c = "a"), then I believe that you can use strncat (you need to check for this):

 char ch = 'a'; strncat(str, &ch, 1); 

In the above code, the delimiter is a local variable that is destroyed after foo is returned. Is it possible to add it to a variable output?

Yes: functions such as strcat and strcpy make deep copies of the original string. They do not leave small pointers behind, so that the fine for local data will be destroyed after these operations.

If I concatenate two null terminating strings, strcat add two null terminating characters to the resulting string?

No, strcat will basically overwrite the null terminator on the dest line and write past it, and then add a new null terminator when it finishes.

+1
source share

How to find out the last character from a string?

Your approach is almost correct. The only way to find the end of line C is to iterate over the characters, look for zero.

There is an error in your answer, though (in the general case). If strlen (str) is zero, you get access to the character before the start of the line.

I have a string and you need to add char to it. How can i do this?

Your approach is wrong. String C is just an array of C characters, and the last is '\0' . Therefore, theoretically, you can add a symbol like this:

 char delimiter = ','; char text[7]; strcpy(text, "hello"); int textSize = strlen(text); text[textSize] = delimiter; text[textSize + 1] = '\0'; 

However, if I leave it this way, I will get a billion votes because there are three places where I have a potential buffer overflow (if I did not know that my original line was β€œhi”). Before making a copy, you need to check that the text is large enough to contain all the characters from the string plus one for the delimiter plus one for the ending nul.

... delimiter is a local variable that is destroyed after foo returns. Can I add it to a variable output?

Yes it's good. strcat copies characters. But your sample code does not verify that the output is large enough for everything you put into it.

If I concatenate two lines with zero termination, will strcat add two zero terminating characters to the resulting string?

Not.

+1
source share

I somehow think this is not the right way because strlen has to iterate over the characters to get the length. So this operation will have O (n) complexity.

You read Joel Spolsky correctly on why C-lines suck . There are several ways around this. The methods include either not using C strings (for example, using Pascal strings, or creating your own library to process them) or not using C (use C ++, which has a class of strings that is slow for various reasons, but you can also write your own to handle Pascal strings easier than in C, for example)

Regarding adding a char string to a C string; string C is just a char array with a nul terminator, if you save the terminator, this is a string, there is no magic.

 char* straddch( char* str, char ch ) { char* end = &str[strlen(str)] ; *end = ch ; end++ ; *end = 0 ; return str ; } 

Like strcat (), you should know that the array created by str is long enough to accommodate a longer string, the compiler will not help you. He is inelegant and unsafe.

If I concatenate two null terminating strings, strcat append two null terminating characters for the resulting string?

No, only one, but what follows is what can happen, that it is zero or something happened in memory. Consider the following equivalent:

 char* my_strcat( char* s1, const char* s2 ) { strcpy( &str[strlen(str)], s2 ) ; } 

the first character s2 overwrites the terminator in s1.

In the above code, the delimiter is a local variable that is destroyed after foo is returned. Is it possible to add it to a variable output?

In your example, delimiter not a string, and initializing a pointer with char does not make sense. However, if it were a string, the code would be fine, strcat () copies the data from the second string, so the lifetime of the second argument does not matter. Of course, in your example, you can use the char function (rather than char *) and the upstream straddch () function.

+1
source share

All Articles