Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中的snprintf()不单独处理目标字符串的最低两个字节_C_String_Pointers_Printf - Fatal编程技术网

C中的snprintf()不单独处理目标字符串的最低两个字节

C中的snprintf()不单独处理目标字符串的最低两个字节,c,string,pointers,printf,C,String,Pointers,Printf,我想写一个小程序,用下面的方法使用snprintf函数反转字符串中的字符。在那里我注意到了一些奇怪的事情 int main() { char dest[5] = ""; char source[5] = "abc"; for (int i = 0; i < 4; i++) { char c = source[i]; snprintf(dest, 5, "%c%s", c, dest); //here, the current

我想写一个小程序,用下面的方法使用snprintf函数反转字符串中的字符。在那里我注意到了一些奇怪的事情

int main() {

    char dest[5] = "";
    char source[5] = "abc";

    for (int i = 0; i < 4; i++) {

        char c = source[i];
        snprintf(dest, 5, "%c%s", c, dest);  //here, the current character gets appended in front
                                             //of the String "dest" using snprintf() "recursively"
    }
}
程序应输出的内容:cba 实际产量:中华公所

调试程序时,您可以看到最低的两个字节dest[0]和dest[1]始终携带相同的信息

有人知道为什么会发生这种情况以及如何预防吗?
如果我在参数中不使用dest两次,而是使用一个临时缓冲区,如:snprintfetemporal,5,%c%s,c,dest和snprintfdest,5,%s,temporary,然后直接使用,一切都会按预期工作。

您所做的是不被允许的。根据第7.21.6.5节关于snprintf功能的内容:

snprintf函数等同于fprintf,只是 输出被写入参数s指定的数组,而不是 去小溪。如果n为零,则不写入任何内容,s可能为null 指针。否则,超过n-1的输出字符将被删除 丢弃而不是写入数组,以及空字符 在实际写入的字符末尾写入 阵列。如果复制发生在重叠的对象之间, 该行为未定义


所以你不能让目的地成为来源之一。您需要写入临时字符串。

系统不允许您这样做。根据第7.21.6.5节关于snprintf功能的内容:

snprintf函数等同于fprintf,只是 输出被写入参数s指定的数组,而不是 去小溪。如果n为零,则不写入任何内容,s可能为null 指针。否则,超过n-1的输出字符将被删除 丢弃而不是写入数组,以及空字符 在实际写入的字符末尾写入 阵列。如果复制发生在重叠的对象之间, 该行为未定义


所以你不能让目的地成为来源之一。您需要写入临时字符串。

如果源和目标重叠,可以使用memmove

#include <stdio.h>
#include <string.h>
int main(){
    char dest[5] = "";
    char source[5] = "abc";
    size_t len = strlen ( source);

    for ( size_t i = 0; i < len; i++) {
        memmove ( &dest[1], &dest[0], len);//move len bytes in array of [5]
        dest[0] = source[i];//set first byte
        dest[len] = 0;//ensure zero terminator
        printf ( "%s\n", dest);
    }
}
如果需要递归,则可以使用它

#include <stdio.h>

size_t strreverse(char *str, size_t index, char *dest) {
    char ch = str[index];
    if(str[index] =='\0') {
        return 0;
    }
    index = strreverse ( str, index + 1, dest);//recursion
    dest[index] = ch;
    return index + 1;
}

int main ( void) {
    char text[] = "abc";
    char result[sizeof text] = "";
    strreverse ( text, 0, result);
    printf("%s\n", text);
    printf("%s\n", result);
    return 0;
}

如果源和目标重叠,则可以使用memmove

#include <stdio.h>
#include <string.h>
int main(){
    char dest[5] = "";
    char source[5] = "abc";
    size_t len = strlen ( source);

    for ( size_t i = 0; i < len; i++) {
        memmove ( &dest[1], &dest[0], len);//move len bytes in array of [5]
        dest[0] = source[i];//set first byte
        dest[len] = 0;//ensure zero terminator
        printf ( "%s\n", dest);
    }
}
如果需要递归,则可以使用它

#include <stdio.h>

size_t strreverse(char *str, size_t index, char *dest) {
    char ch = str[index];
    if(str[index] =='\0') {
        return 0;
    }
    index = strreverse ( str, index + 1, dest);//recursion
    dest[index] = ch;
    return index + 1;
}

int main ( void) {
    char text[] = "abc";
    char result[sizeof text] = "";
    strreverse ( text, 0, result);
    printf("%s\n", text);
    printf("%s\n", result);
    return 0;
}

不能将字符串打印到自身:如果dest是第一个参数,即要打印到的字符串,则不能将其用作格式后面的任何参数。对于int i=0;i<4;i++将abc中的nul字节读取为c,然后在snprintfdest,5,%c%s,c,dest;中的字符串前面加上前缀;。是的,正如@MOehm所指出的,如果字符串重叠,则调用未定义的行为,或者递归地误用该词。您的代码与递归无关。您不能将字符串打印到自身:如果dest是第一个参数,即您要打印到的字符串,则不能将其用作格式后面的任何参数。对于int i=0;i<4;i++将abc中的nul字节读取为c,然后在snprintfdest,5,%c%s,c,dest;中的字符串前面加上前缀;。是的,正如@MOehm所指出的,如果字符串重叠,则调用未定义的行为,或者递归地误用该词。您的代码与递归无关。