我正在编写此代码以反转字符串,但不知何故,最后printf()
似乎无法打印出更新字符串。我想知道原因。
#include <stdio.h>
int main() {
char x[] = "abcdefghijklmn";
int j = sizeof(x);
int i = 0;
char t = 'a';
printf("%s,%i\n", x, j / 2);
for (; i < j / 2; i++) {
t = x[i];
x[i] = x[j - i - 1];
x[j - i - 1] = t;
printf("%c,%i,%i\n", x[i], i, j - i - 1);
}
printf("%s\n", x);
return 0;
}
strlen()
之间的区别,也是是一种更简单的方法来反转你的字符串。检查并留下您的评论。
#include <stdio.h>
#include <string.h>
void StringReverse(char *s) {
int i = 0;
int j = strlen(s) - 1;
printf("sizeof:%i,strlen:%i\n",sizeof(s),strlen(s));
for (; i < j + 1; i++)
printf("%c", s[j - i]);
}
int main() {
char x[] = "abcdefghijklmn";
printf("sizeof:%i,strlen:%i\n",sizeof(x),strlen(x));
StringReverse(x);
return 0;
}
结果是:
sizeof:15,strlen:14
sizeof:4,strlen:14
nmlkjihgfedcba
然后检查一下:
#include <stdio.h>
#include <string.h>
void StringReverse(char *s) {
int i = 0;
int j = strlen(s) - 1;
printf("sizeof:%i,strlen:%i\n",sizeof(s),strlen(s));
for (; i < j + 1; i++)
printf("%c", s[j - i]);
}
int main() {
char x[100];
puts("Input a tring to reverse:");
fgets(x,100,stdin);
printf("sizeof:%i,strlen:%i\n",sizeof(x),strlen(x));
StringReverse(x);
return 0;
}
结果是:
Input a tring to reverse:
abcdefghijklmn
sizeof:100,strlen:15
sizeof:4,strlen:15
nmlkjihgfedcba
现在很清楚,strlen()
总是尝试给出字符串的实际长度,但为什么第一个长度是14,第二个输入方式是15?
sizeof()
由您放入char x []的数字定义,始终包含EOS;
并且指针变量为字符串,sizeof()
总是返回指针长度而不是字符串长度。
【感谢@David C. Rankin】你的代码提醒我,数组变量总是被用作传递给函数的指针,因此无论你是什么,原始字符串总是不保存使用常用功能(下面的第一个代码)或指向功能的指针(下面的第二个代码)。正确的吗?
第一
#include <stdio.h>
#include <string.h>
void StringReverse(char *s) {
int i = 0;
int j = strlen(s);
printf("sizeof:%i,strlen:%i\n",sizeof(s),strlen(s));
char t = 'a';
for (; i < j / 2; i++) {
t = s[i];
s[i] = s[j - i - 1];
s[j - i - 1] = t;
}
printf("%s\n", s);
}
int main() {
char x[]="abcdefghijklmn";
/* if you instead write char *x="abcdefghijklmn"; here
the compiler will encounter error, because a pointer to
a 【string literal】 can not be used to modify the string.
*/
printf("sizeof:%i,strlen:%i\n",sizeof(x),strlen(x));
StringReverse(x);
printf("\n%s\n", x); //original string x is not preserved.
return 0;
}
结果是:
sizeof:15,strlen:14
sizeof:4,strlen:14
nmlkjihgfedcba
nmlkjihgfedcba
第二
#include <stdio.h>
#include <string.h>
char *StringReverse(char *s) {
int i = 0;
int j = strlen(s);
printf("sizeof:%i,strlrn:%i\n", sizeof(s), strlen(s));
char t = 'a';
for (; i < j / 2; i++) {
t = s[i];
s[i] = s[j - i - 2];
s[j - i - 2] = t;
}
return s;
}
int main() {
char x[100];
puts("Input a tring to reverse:");
fgets(x, 100, stdin);
printf("sizeof:%i,strlrn:%i\n", sizeof(x), strlen(x));
StringReverse(x);
printf("\n%s\n", x); //original string x is not preserved.
return 0;
}
结果是:
Input a tring to reverse:
abcdefghijklmn
sizeof:100,strlrn:15
sizeof:4,strlrn:15
nmlkjihgfedcba
因此,如果您想保留原始字符串,则必须使用其他方式:
......继续
答案 0 :(得分:1)
无效版
(提示:将指针传递给要反转的字符范围的开头和结尾字符)
/** strreverse - reverse string given by begin and end pointers.
* Takes valid string and swaps src & dest each iteration.
* The original string is not preserved.
* If str is not valid, no action taken.
*/
void strreverse (char *begin, char *end)
{
char tmp;
if (!begin || !end) {
printf ("%s() Error: invalid begin or end\n", __func__);
return;
}
while (end > begin)
{
tmp = *end;
*end-- = *begin;
*begin++ = tmp;
}
}
修改原始
的char*
版本
/** strrevstr - reverse string, swaps src & dest each iteration.
* Takes valid string and reverses, original is not preserved.
* If str is valid, returns pointer to str, NULL otherwise.
*/
char *strrevstr (char *str)
{
if (!str) {
printf ("%s() Error: invalid string\n", __func__);
return NULL;
}
char *begin = str;
char *end = str + strlen (str) - 1;
char tmp;
while (end > begin)
{
tmp = *end;
*end-- = *begin;
*begin++ = tmp;
}
return str;
}
保留(复制)原始
的char*
版本
/** strrevdup - reverse duplicate string, swaps src & dest each iteration.
* Takes valid string, duplicates and reverses, original is preserved.
* Returns pointer to reversed string on success, NULL otherwise.
* Requires string.h, caller is responsible for freeing memory allocated.
*/
char *strrevdup (char* str)
{
if (!str) {
printf ("%s() Error: invalid string\n", __func__);
return NULL;
}
char *rstr = strdup (str);
char *begin = rstr;
char *end = rstr + strlen (rstr) - 1;
char tmp;
while (end > begin){
tmp=*end;
*end-- = *begin;
*begin++ = tmp;
}
return rstr;
}
答案 1 :(得分:0)
代码中的问题是使用sizeof()
运算符。你的使用方式
int j = sizeof(x);
在这种情况下,不正确。你想要的是利用strlen()
头文件中的string.h
函数。
案例1:
sizeof()
运算符返回数据类型的 size 。 x
是一个char
的数组,当使用字符串文字"abcdefghijklmn"
初始化时,它需要15
char
s。 [14个字母+ 1个终止空。]来存储值。
因此,sizeof(x)
将返回15
。
案例2:
OTOH,strlen()
不计算终止空值,因此strlen(x)
将返回14
。
接下来,如我们所知,C
中的数组索引为0-based
,这意味着由n
元素组成的数组将具有从0
到{{{ 1}}。
因此,在情况1中,在使用值n-1
时,我们引用了终止空值,它将被复制并放入j-1
索引,基本上标记结束的字符串。因此,在将反向数组打印为字符串时,第一个元素beinh null标记字符串的结尾,并且不输出任何内容。
OTOH&LT;在案例2中,使用值0
,我们指的是数组j-1
中存在的最后一个 alphanbetic char
值,它将被复制到第x
个索引。复制将以这种方式继续,并且我们将按步调颠倒字符串。
答案 2 :(得分:0)
只需更改此行
即可int j = sizeof(x);
要
int j = sizeof(x)-1;
由于sizeof(x)
将返回15(14个数组字符和1个空字符)
数组索引从0到13的位置。
i=0;
和j
为15。
x[i] = x[j - i - 1]; //x[0] = x[15-0-1]; i.e x[14] which is NULL.
由于x[14]
是空字符,分配给x[0]
因此,在打印字符串时,它首先在字符串终止处获得空字符,这就是为什么它不提供任何输出。
我总是希望使用strlen
来获取字符串的长度,因为它不包含空字符
在第二个想法中你也可以使用
int j = strlen(x); // this will return 14.
使用&#34; string.h&#34;头文件使用此功能。
答案 3 :(得分:0)
尝试打印相反的字符串:
for (i = 1; i < sizeof(x); i++)
printf("%c", x[i]);
而不是:
printf("%s\n", x);
答案 4 :(得分:0)
数组的最后一个字符是&#39; \ 0&#39;,无法反转
#include <stdio.h>
int main() {
char x[] = "abcdefghijklmn";
int j = sizeof(x);
int i = 0;
char t = 'a';
printf("%s,%i\n", x, j / 2);
for (; i < j / 2; i++) {
t = x[i];
x[i] = x[j - i - 2];
x[j - i - 2] = t;
printf("%c,%i,%i\n", x[i], i, j - i - 2);
}
printf("%s\n", x);
return 0;
}
答案 5 :(得分:0)
sizeof()
将返回带有null
终止字节的值。它会导致循环运行一次迭代。
所以改成这样,
int j=sizeof(x)-1;
或者使用strlen
功能。
包含头文件#include<string.h>
int j=strlen(x);