开发者

Cast char to char array or char array to char?

So let's say I have a cha开发者_如何学Cr and I want to strcat() it to a char array in a single line of code. For [a non-practical] example:

strcat("ljsdflusdfg",getchar());

Or I wanted to do the reverse, what would be the appropriate function to concat or typecast strings, regardless of data type? Or perhaps there is some syntax I'm missing...

Here's an example. It compiles just fine but crashes.

char* input(){
 char* inp="";
 while(1){
  char c=getchar();
  if(c){
   if(c=='\n'||c==EOF){
    break;
   }else{
    strcat(inp,(char*)c);
   }
  }
 }
 return inp;
}


strcat treats its argument as a pointer to a nul-terminated string. Casting a char to a char * is just dangerous, and I can imagine no reason it would ever be useful (not to imply that you're stupid for trying it - everyone makes silly mistakes when they learn. That's why we're here.)

The reason is that it would interpret the single byte char, plus the extra sizeof(char*) - sizeof(char) (usually 3) bytes surrounding that char, as a pointer, which would point to... anywhere. You have no way of knowing where it points, since 3 of those bytes are beyond your control, and thus no way of knowing whether it points to valid data.

You might take this as a second approach:

strcat(inp, &c);

This time, you'd be doing better, since &c is an expression of type char * and no casts are required. But again, strcat assumes it's argument is a nul-terminated string, and since you have no way of guaranteeing a nul byte after your char data, this won't do.

The best way is this:

size_t len = strlen(inp); // this may already be calculated somewhere else
...
inp[len++] = c; // add c as the last character, and adjust our len
inp[len] = '\0'; // add a new nul terminator to our string

UPDATE:

Actually, I lied. The best way is to use the standard library function fgets, which appears to be doing more or less what you're trying to do. Truthfully I forgot it, but if this is a homework assignment your professor may not want you using fgets so that you can learn how to do it manually. However, if this isn't homework, fgets does exactly what you're looking for. (Actually, the third approach is well on its way to reimplementing fgets or fgets-like functionality.)

I would also add some other commentary on your input function:

  1. char* inp = ""; will point to read-only data. A flaw in the C standard (for backwards compatability) allows string literals to be assigned to char* types instead of const char * types as it (IMHO) should be.

    There are several ways to approach this, but the best is dynamic allocation. Use the malloc function to reserve some data, keep track of how much you've used in your function, and use the realloc function if you end up needing more room to store it. If you need help with that, I'm sure you'll be back here (hopefully not too soon) with another question. :)
  2. getchar() returns an int, because EOF is defined to be outside the normal range of a char. In order to distinguish between any char and EOF, it's best to make c an int. Otherwise a perfectly valid character may signal EOF. Be sure to cast c down to a char when you add it to the string, though.


strcat(inp,(char*)c);

That is trying to concat the contents of the memory at where ever 'c' (as a memory location) is until it finds a zero.

A better way is to create an empty string of whatever maximum size you think is reasonable, fill it with zeros and then just insert 'c' at the current last position


If you wish to concatenate a single char onto a string, you can use strncat() and specify the number of characters to concatenate as 1. But note that:

  • The destination buffer must have sufficient space; and
  • In C89, you must have an actual char object to take the address of (so you can't directly concatenate the result of getchar().

For example:

char str[5] = "foo";
char c;
int ch;

if ((ch = getchar()) != EOF) {
    c = ch;
    strncat(str, &c, 1);
}

In C99, you can use a compound literal and the second restriction does not apply:

char str[5] = "foo";
int ch;

if ((ch = getchar()) != EOF) {
    strncat(str, &(char){ ch }, 1);
}


This won't work because the *inp char pointer doesn't have any memory backing it up. When you declared it to be char *inp = "";, you only gave it the address of an empty string. If you had given the following declaration char *inp = "abcdefg", then you could have written 7 chars to it before you overwrote the '\0' and got into trouble.

You will need to dynamically increase the size of the backing memory as you input more and more characters. You will also have the problem of knowing when to free the memory so you don't get memory leaks.

Also, your strcat needs to have '&' before the c.


First off, you are returning a pointer to a stack allocated array. This is undefined bahavior. Secondly, you are attempting to write chars into unallocated memory. Thirdly, the type of inp is const char* not char*.

You want something like:

char* input(char *dest) {
  strcpy(dest,"");
  while(1){
  char c=getchar();
  if(c){
   if(c=='\n'||c==EOF){
    break;
   }else{
    strcat(inp,&c);
   }
  }
 }
 return dest;
}


Your code crashes because strcat expects null-terminated strings for both its parameters.

If you want to concatenate a char, you need to first create a null-terminated string from it.

char c[2] = {0,0};
c[0] = getchar();
strcat(inp, c);

But don't use strcat, unless you can guarantee that the input string has allocated space for that extra character. Better to you strncat which also includes a parameter for the amount of space in the first parameter (the dest).

I recommend reading this first.


One simple way is to use snprintf:

char newString[50+1];
snprintf(newString, sizeof(newString), "%s%c", "ljsdflusdfg", getchar());

It's a simple solution, but does require that you roughly know how big the string is going to be ahead of time.

Notes: I use the +1 to remind myself that there needs to be room for the null termination, and snprintf is better than sprintf as it is given the size of the buffer to prevent buffer overrun.


Cast char to char array?
It's just like saying you want to cast a char into string.
You just can't do that directly.
Instead of char, place it in an array (myChar[]).
Afterwhich, strcat it with your original char array.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜