简体   繁体   English

C将char附加到char *

[英]C appending char to char*

So I'm trying to append a char to a char* . 所以我试图将char添加到char*

For example I have char *word = " "; 例如,我有char *word = " "; I also have char ch = 'x'; 我也有char ch = 'x';

I do append(word, ch); append(word, ch); Using this method.. 使用这种方法..

void append(char* s, char c)
{

    int len = strlen(s);
    s[len] = c;
    s[len+1] = '\0';
}

It gives me a segmentation fault, and I understand why I suppose. 它给了我一个分段错误,我理解为什么我想。 Because s[len] is out of bounds. 因为s[len]超出范围。 How do I make it so it works? 我该如何制作呢? I need to clear the char* a lot as well, if I were to use something like char word[500]; 我需要清除char* ,如果我要使用char word [500]之类的东西; How would I clear that once it has some characters appended to it? 一旦附加了一些字符,我该如何清除? Would the strlen of it always be 500 ? 它的strlen总是500 Thanks in advance. 提前致谢。

Typical C practice would be like: 典型的C练习如下:

//returns 1 if failed, 0 if succeeded 
int  append(char*s, size_t size, char c) {
     if(strlen(s) + 1 >= size) {
          return 1;
     }
     int len = strlen(s);
     s[len] = c;
     s[len+1] = '\0';
     return 0;
}

When passing a function an array to modify the function has no idea at compile time how much space it has. 传递函数时,一个数组来修改函数,在编译时不知道它有多少空间。 Usual practice in C is to also pass the length of the array, and the function will trust this bound and fail if it can't do its work in the space it has. C中的常规做法是传递数组的长度,如果函数不能在它所拥有的空间中完成它,函数将信任该约束并失败。 Another option is to reallocate and return the new array, you would need to return char* or take char** as an input but you must think carefully of how to manage heap memory in this situation. 另一种选择是重新分配并返回新数组,您需要返回char*或将char**作为输入,但在这种情况下您必须仔细考虑如何管理堆内存。 But without reallocating, yes, your function must somehow fail if it is asked to append when there is no space left, it's up for you for how to fail. 但是如果没有重新分配,是的,如果在没有空间的情况下要求追加,你的函数必须以某种方式失败,这取决于你如何失败。

It is hard to append to a string in-place in C. Try something like this: 尝试在C中就地添加字符串很难。尝试这样的事情:

char *append(const char *s, char c) {
    int len = strlen(s);
    char buf[len+2];
    strcpy(buf, s);
    buf[len] = c;
    buf[len + 1] = 0;
    return strdup(buf);
}

Be sure to deallocate the returned string when done with it. 完成后,请务必释放返回的字符串。

FYI: It segfaults probably because the string you are passing is stored in read-only memory. 仅供参考:可能因为您传递的字符串存储在只读存储器中而导致段错误。 But you're right, you are also writing off of the end (the [len+1] write, not the [len] one). 但是你是对的,你也是写完了( [len+1]写,而不是[len] )。

If you're passing in 如果你要传入

append("foo", 'X');

it will crash, because foo is normally put in readonly storage. 它会崩溃,因为foo通常放在只读存储器中。 Even if it isn't it will overwrite something bad probably! 即使不是它也可能会覆盖不好的东西! In this case the compiler if it's kind should warn you of conversion from const char * to char * which would be a clue. 在这种情况下,编译器是否应该警告您从const char *到char *的转换,这将是一个线索。

Yes, the assumption you made is - almost - correct - the crash may be because you're trying to write past the bounds of the string (actually only s[strlen(s) + 1] is out of bounds, because s[strlen(s)] is still a valid location - the terminating NUL byte is stored there). 是的,你做的假设是 - 几乎 - 正确 - 崩溃可能是因为你试图写过字符串的边界(实际上只有s[strlen(s) + 1]超出范围,因为s[strlen(s)]仍然是一个有效的位置 - 终止NUL字节存储在那里)。 But you also can't modify a string literal, because it's usually in some readonly part of the process memory. 但是你也无法修改字符串文字,因为它通常位于进程内存的某些只读部分。 Both of these actions lead to invocation of undefined behavior, which have the potential of crashing. 这两个操作都会导致调用未定义的行为,这些行为可能会崩溃。 You can solve this problem by copying the string to a dynamically allocated storage then modifying the copy. 您可以通过将字符串复制到动态分配的存储,然后修改副本来解决此问题。 Also, you're supposed to use const char * in the argument of your function, because char * suggests that read-only strings can't be passed in. 此外,您应该在const char *的参数中使用const char * ,因为char *表示无法传入只读字符串。

char *append(const char *orig, char c)
{
    size_t sz = strlen(orig);
    char *str = malloc(sz + 2);
    strcpy(str, orig);
    str[sz] = c;
    str[sz + 1] = '\0';
    return str;
}

Also, don't forget to free() the returned string when it's not needed anymore. 另外,当不再需要时,不要忘记free()返回的字符串。

You can't really safely append to an arbitrary string, because firstly, string constants tend to be in read-only memory, so trying to write to them is likely to result in a segmentation fault, and secondly, you have no guarantee that if they've passed you a buffer that you haven't shot over the end of it. 你不能真正安全地附加到任意字符串,因为首先,字符串常量往往是在只读内存中,所以尝试写入它们可能会导致分段错误,其次,你不能保证如果他们已经通过了你一个缓冲区,你还没有完成它。

In particular, if you do char x[500]; 特别是,如果你做char x [500];

there's no guarantee that strlen(x) will return you 500. It will return you how many characters it has to count forward from the start of x before it reaches a null. 不能保证strlen(x)会返回500.它将返回它在x到达null之前从x的开头向前计数的字符数。 It could return you 0, 1 ... 500, 501 ..., depending on what is in x. 它可能会返回0,1 ... 500,501 ......,具体取决于x中的内容。

Really your only options are to call append with the size of the buffer you are appending to (so you can do something appropriate if the buffer is full), or to make append allocate a new buffer every time it is called, in which case you will need to free the buffer again of course. 实际上你唯一的选择就是调用append和你要附加的缓冲区的大小(这样你可以在缓冲区已满时做一些适当的事情),或者让append在每次调用时分配一个新的缓冲区,在这种情况下你当然需要再次释放缓冲区。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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