#include <stdio.h>
#define slice(bare_string,start_index) #bare_string+start_index
#define arcane_slice(bare_string,start_index) "ARCANE" #bare_string+start_index
int main(){
printf("slice(FIRSTA,0)==> `%s`\n",slice(FIRSTA,0));
printf("slice(SECOND,2)==> `%s`\n",slice(SECOND,2));
printf("slice(THIRDA,5)==> `%s`\n",slice(THIRDA,5));
printf("slice(FOURTH,6)==> `%s`\n",slice(FOURTH,6));
printf("slice(FIFTHA,7)==> `%s`\n",slice(FIFTHA,7));
printf("arcane_slice(FIRSTA,0)==> `%s`\n",arcane_slice(FIRST,0));
printf("arcane_slice(SECOND,2)==> `%s`\n",arcane_slice(SECOND,2));
printf("arcane_slice(THIRDA,5)==> `%s`\n",arcane_slice(THIRDA,5));
printf("arcane_slice(FOURTH,6)==> `%s`\n",arcane_slice(FOURTH,6));
printf("arcane_slice(FIFTHA,7)==> `%s`\n",arcane_slice(FIFTHA,7));
return 0;
}
输出:
slice(FIRSTA,0)==> `FIRSTA`
slice(SECOND,2)==> `COND`
slice(THIRDA,5)==> `A`
slice(FOURTH,6)==> ``
slice(FIFTHA,7)==> `slice(FIFTHA,7)==> `%s`
`
arcane_slice(FIRSTA,0)==> `ARCANEFIRST`
arcane_slice(SECOND,2)==> `CANESECOND`
arcane_slice(THIRDA,5)==> `ETHIRDA`
arcane_slice(FOURTH,6)==> `FOURTH`
arcane_slice(FIFTHA,7)==> `IFTHA`
我有上面的C代码,我需要帮助。我从中获得了奇怪的行为
应该从传递的索引中“切片”的类似函数的宏slice
到字符串的末尾。它没有真正意义上的切片但是通过了
指向某个点的指针printf
从该点开始打印
地址。我已经设法在arcane_slice
中找出了字符串
首先连接然后'切片'。我也想到了start_index
时的情况
等于6 printf
从空字节开始打印,这就是为什么
你得到'空'字符串。奇怪的部分是start_index
是7.它打印
printf
的第一个参数(插补器字符串)与两者中传递的裸字符串相连
arcane_slice
和slice
(如输出中的第5行和第10行所示)
为什么会这样?
我最大的猜测是当start_index
超过琴弦的长度时,
指针指向程序地址空间中数据段的开头。但
然后你可以用“为什么不从FIRSTA
开始打印”
答案 0 :(得分:1)
没有任何“数据段”,堆栈。这就是我记得的:当C调用一个函数时,它首先将数据放在堆栈上,第一个是变量参数,然后是格式,所有这些都是按顺序分配文本的内存地址。在那个内存块中,最后一个参数(c-string)首先出现,第一个参数变为最后一个,因此:
内存:
"FIFTHA\0slice(FIFTHA,7)==> `%s`\n\0"
参数:
<pointer-to-"FIFTHA"> <pointer-to-"slice...">
由于你过度增加第一个字符,它会跳过'\0'
字符并指向该格式。
尝试使用更多占位符进行试验,例如
printf("1: %s, 2: %s\n", slice(FIFTHA,7), slice(FIFTHA,6));
答案 1 :(得分:0)
slice(bare_string,start_index) #bare_string+start_index
您正在传递string
和bare_string
存储您已经过的字符串的起始地址,然后返回更改的指针位置bare_string+start_index
char str[6]="Hello";
char *ptr =str;
printf("%s\n",str);//prints hello
printf("%s\n",str+1);//prints ello
printf("%s\n",str+2);//prints llo
printf("%s\n",str+3);//prints lo
printf("%s\n",str+4);//prints o
printf("%s %c=%d \n",str+5,*(str+5),*(str+5));//prints Null
printf("%s %c=%d \n",str+6,*(str+6),*(str+6));//prints Null or may be Undefined behavior
printf("%s %c=%d \n",str+7,*(str+7),*(str+7));//prints Null or may be Undefined behaviour
同样的情况正在你的案件中肆虐。
测试代码:
#include<stdio.h>
main()
{
char str[6]="Hello";
char *ptr =str;
printf("%s\n",str);//prints hello
printf("%s\n",str+1);//prints ello
printf("%s\n",str+2);//prints llo
printf("%s\n",str+3);//prints lo
printf("%s\n",str+4);//prints o
printf("%s %c=%d \n",str+5,*(str+5),*(str+5));//prints Null
printf("%s %c=%d \n",str+6,*(str+6),*(str+6));//prints Null or may be Undefined behavior
printf("%s %c=%d \n",str+7,*(str+7),*(str+7));//prints Null or may be Undefined behaviour
}
答案 2 :(得分:0)
您自己已回答了自己的问题。 "FIFTHA"+7
为您提供了一个指向字符串对象外部的指针,这是C中未定义的行为。
没有简单的方法可以在C中为这样的“切片”获得类似Python的行为。通过在字符串中添加一个后缀来填充零字节,可以使索引适用于某个上限:< / p>
#define slice(bare_string,start_index) ((#bare_string "\0\0\0\0\0\0\0")+(start_index))
此外,在使用宏时,过度使用括号是一种很好的做法(也可以避免错误)。
#define slice(bare_string,start_index) ((#bare_string)+(start_index))
#define arcane_slice(bare_string,start_index) (("ARCANE" #bare_string)+(start_index))