尝试练习K& R 2nd ed。的练习1-19,例如编写一个函数来反转字符串。我以为我管理了,但打印输出看起来很奇怪:-)如果我使用STRINGSIZE 5
输出是
Original String: hello
Reversed String: ollehhello
。如果我使用STRINGSIZE 6
来记住'\0'
字符串结尾字符并将while循环修改为while ((outputString[STRINGSIZE - (i + 2)] = inputString[i]) != '\0')
,那么我得到Original String: hello
Reversed String: olleh?hello
,我想{{1}来自?
的一些随机字符添加到位置5的while循环中的反向字符串;但是再次添加了'\0'
。任何人都可以解释为什么hello
被添加到hello
的末尾,我怎样才能摆脱它以便我只得到正确的反向字符串?
以下是代码:
olleh
答案 0 :(得分:2)
首先,字符数组reversedString[]
没有足够的空间来存储字符串"hello"
的空终止符。一种选择是在这里使用可变长度数组:
char reversedString[strlen(stringToReverse) + 1];
VGA在C99中引入,并在C11中可选。我记得它,K& R不包括可变长度阵列的覆盖范围,因为即便是第二版也是在此之前发布的。
与C89兼容的另一个选项是使用sizeof
运算符:
char stringToReverse[] = "hello";
char reversedString[sizeof stringToReverse];
这里,sizeof
运算符的结果在编译时是已知的,并且可以用于声明固定大小的数组。与strlen("hello")
的结果相比,此大小包含空终止符的空间。请注意,这不适用于char *stringToReverse = "hello";
,因为sizeof
运算符会给出指针的大小。如果先将stringToReverse
传递给函数,这也不会起作用,因为那时数组名称将衰减为指向stringToReverse
的第一个元素的指针。
在reverseString()
函数中,需要确定inputString
的长度(因为不再使用STRINGSIZE
);这可以使用strlen()
或循环来完成。然后,关键的是,函数必须确定在返回之前向\0
添加空终止符(outputString[]
)。另请注意,在return
的末尾添加了main()
语句,以使其真正与C89兼容:
#include <stdio.h>
void reverseString (char inputString[], char outputString[]);
int main(void) {
char stringToReverse[] = "hello";
char reversedString[sizeof stringToReverse];
reverseString(stringToReverse, reversedString);
printf("Original String: %s\nReversed String: %s\n",
stringToReverse, reversedString);
return 0;
}
void reverseString(char inputString[], char outputString[])
{
int length = 0;
int i = 0;
/* Get inputString length; or use strlen() */
while (inputString[length] != '\0') {
++length;
}
/* Copy to outputString[] in reverse */
while (i < length) {
outputString[i] = inputString[(length - i) - 1];
++i;
}
/* Add null terminator */
outputString[i] = '\0';
}
答案 1 :(得分:1)
首先,我建议您更改此行:
char reversedString[STRINGSIZE];
到
char reversedString[strlen(stringToReverse) + 1]; // + 1 to make room for the string termination
然后我会做类似的事情:
void reverseString (char inputString[], char outputString[]) {
int i;
int len = strlen(inputString);
for(i=0; i<len; ++i)
{
outputString[len-i-1] = inputString[i];
}
outputString[len] = '\0'; // Terminate the string
}