[英]String reversal in C: What is it I am doing wrong?
我正在閱讀K&R C,主要是為了刷我的C技能,並且在嘗試編寫程序來反轉給定的字符串時,我有一個困擾的錯誤, 最糟糕的是,我無法調試 - 也沒有可能是什么原因造成的。
我的代碼如下:
#include <stdio.h>
#include <string.h>
char * reverse(char *string);
int main(int argc, char *argv[])
{
printf("Please input a string: \t");
char string[256];
scanf("%s", string);
char *reversed = reverse(string);
printf("The reversed string is %s\n", reversed);
return 0;
}
char * reverse(char string[])
{
int size = strlen(string);
printf("DEBUG: The size of the string that we got as input was: %d\n", size);
int counter;
char reversed[size + 1];
for(counter = size - 1; counter >= 0; counter--) {
reversed[size - counter] = string[counter];
printf("DEBUG: The character copied now was %c and was at index %d\n", string[counter], counter);
}
reversed[size + 1] = '\0';
printf("DEBUG: The reversed string is %s\n", reversed);
return reversed;
}
(請原諒那些亂丟代碼邏輯的調試語句。除此之外,請隨時糾正您可能看到的任何錯誤,並隨時提出建議以改進它)
現在,我的代碼正在工作(大部分),但錯誤是它復制了我沒有輸入的字符。 以下是兩次測試運行的(有趣)結果:
第一個:
nlightnfotis@crunchbang:~/SoftwareExperiments$ ./reverse
Please input a string: fotis
DEBUG: The size of the string that we got as input was: 5
DEBUG: The character copied now was s and was at index 4
DEBUG: The character copied now was i and was at index 3
DEBUG: The character copied now was t and was at index 2
DEBUG: The character copied now was o and was at index 1
DEBUG: The character copied now was f and was at index 0
DEBUG: The reversed string is $sitof
The reversed string is $sitof
(注意$
)
第二個:
nlightnfotis@crunchbang:~/SoftwareExperiments$ ./reverse
Please input a string: lol
DEBUG: The size of the string that we got as input was: 3
DEBUG: The character copied now was l and was at index 2
DEBUG: The character copied now was o and was at index 1
DEBUG: The character copied now was l and was at index 0
DEBUG: The reversed string is lol
The reversed string is lol
這里更准確地描述:
有沒有比我更有知識和經驗的人向我解釋我的代碼有什么問題,或者可能會給我一個暗示,為什么我面對這個令人沮喪的錯誤?
您正在返回一個局部變量:
char * reverse(char string[]) {
char reversed[size + 1];
....
return reversed;
}
在堆棧上分配的局部變量reversed
,一旦函數reverse
返回就不再存在。 所以從main
引用它會導致未定義的行為。
要解決此問題,您可以執行以下任一操作:
使函數為void
並修改輸入數組。
聲明數組reversed
為靜態,使得其壽命更改程序的生命周期。
動態分配(以及后來取消分配) reversed
總是一樣的錯誤,一遍又一遍......
一世。
char reversed[size + 1];
// ...
return reversed;
您將返回一個自動數組,該函數在函數返回時超出范圍 - 未定義的行為。 使reversed
一個static
變量以避免這種情況(然后在你開始相信它的魔力之前讀取static
關鍵字)。
II。
char string[256];
scanf("%s", string);
輸入帶有空格的字符串時可能存在緩沖區溢出和錯誤。 將此更改為
fgets(string, sizeof(string), stdin);
III。
char reversed[size + 1];
// ...
reversed[size + 1] = '\0';
另一個緩沖區溢出。 在C中,數組從0開始索引。
是時候讀一本好的C書了。
除了codaddict的帖子和H2CO3的漂亮解釋,你還有一個錯誤:
char reversed[size + 1];
reversed[size + 1] = '\0';
這將導致出界索引。 說size = 10
,然后size +1 =11
。 reversed
的char數組的索引值是0,1,2,3,...,10
。 因此, reversed[11]
會讓你陷入困境。
好的,注釋上面發現的錯誤加上我自己的答案:
char * reverse(char string[])
{
int size = strlen(string);
printf("DEBUG: The size of the string that we got as input was: %d\n", size);
int counter;
/* BUGBUG: You are using a stack variable to store the return string.
* char *reversed = malloc(sizeof(char) * (size + 1))
* to allocate a string that can be returned safely.
*/
char reversed[size + 1];
for(counter = size - 1; counter >= 0; counter--) {
/* BUGBUG: You are setting the wrong char in "reversed", it should be
* reversed[size - 1 - counter]. You want the "size - 1" char from the original
* to be copied to the 0 position of the reversed
*/
reversed[size - counter] = string[counter];
printf("DEBUG: The character copied now was %c and was at index %d\n", string[counter], counter);
}
/* BUGBUG: You are setting the null character one past the end of the string.
* Here you want reversed[size], which with 0-indexing is the size+1'st
* character.
*/
reversed[size + 1] = '\0';
printf("DEBUG: The reversed string is %s\n", reversed);
/* BUGBUG: Just to stress this -- you cannot expect this to work; that it
* does so is accidental because the call stack is not cleaned. If the calling
* function called another function (say printf) then the printf is likely to
* overwrite the contents of reversed.
*/
return reversed;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.