[英]Why is my function to reverse string in c not working?
我正在編寫一些 C 代碼,用戶在其中輸入所需的字符串大小,然后將字符串反轉然后打印(而不是反向打印。)我還想提一下,我不想使用外部庫,重點是能夠手動完成。 我使用動態 memory 分配來創建用戶輸入大小的字符串,並稱為“反向數組”function。 在調用 function 之前一切正常。 我反轉字符串的方法遵循與反轉普通數組相同的原則,但不是移動整數,而是移動字符。 你能向我解釋我做錯了什么嗎?
我的代碼:
#include <stdio.h>
#include <stdlib.h>
int RvsArr(char *Str, int end)
{
int start = 0;
char tmp;
while (start < end)
{
tmp = Str[start];
Str[start] = Str[end];
Str[end] = tmp;
start++;
end--;
}
printf("%s", Str);
return 0;
}
int main()
{
int ArrSz;
printf("Please enter array size: ");
scanf("%i", &ArrSz);
char *Str;
Str = (char *)malloc(ArrSz * sizeof(char));
printf("Please enter your string: ");
scanf("%s", Str);
RvsArr(Str, ArrSz);
free(Str);
return 0;
}
您需要反轉實際的字符串,而不是整個緩沖區。
char *RvsArr(char* Str)
{
char *end, *wrk = Str;
char tmp;
if(wrk && *wrk)
{
end = Str + strlen(wrk) - 1;
while(wrk < end)
{
tmp = *wrk;
*wrk++ = *end;
*end-- = tmp;
}
}
return Str;
}
int main()
{
int ArrSz;
printf("Please enter array size: ");
scanf(" %i", &ArrSz);
char* Str;
Str = malloc(ArrSz * sizeof(char));
printf("Please enter your string: ");
scanf(" %s", Str);
printf("\n`%s`\n", RvsArr(Str));
free(Str);
return 0;
}
對於初學者,用戶可以輸入一個字符串,其大小可以小於存儲該字符串的動態分配的字符數組的大小。
所以傳遞數組的大小沒有意義。 數組的大小與輸入的字符串的大小不同。
此表達式Str[end]
在 while 循環的第一次迭代中訪問超出分配數組的 memory。
而且返回類型int
也沒有任何意義。
除此之外 function 不應該 output 任何東西。 function 的調用者將決定 output 結果字符串與否。
注意這個電話
scanf("%s", Str);
不安全。 最好使用 function fgets。 例如
fgets( Str, ArrSz, stdin );
在這種情況下,您需要將 function 可以 append 的新行字符'\n'
刪除到輸入的字符串中。
在不使用標准字符串函數的情況下,function 可以按以下方式定義,如下面的演示程序所示。 function 不是無意義的返回類型int
,而是返回一個指向反轉字符串的第一個字符的指針。
#include <stdio.h>
char * RvsArr( char *s )
{
char *last = s;
while ( *last ) ++last;
if ( last != s )
{
for ( char *first = s; first < --last; ++first )
{
char c = *first;
*first = *last;
*last = c;
}
}
return s;
}
int main(void)
{
char s[] = "Hello World!";
puts( s );
puts( RvsArr( s ) );
return 0;
}
程序 output 是
Hello World!
!dlroW olleH
如果允許您使用標准字符串函數,則 function RvsArr 可以如下所示(前提是包含 header <string.h>
)
char * RvsArr( char *s )
{
char *last = s + strlen( s );
if ( last != s )
{
for ( char *first = s; first < --last; ++first )
{
char c = *first;
*first = *last;
*last = c;
}
}
return s;
}
字符 arrays 或 c 中的字符串(通常稱為)需要一個額外的字節來存儲 null 字符( '\o'
或0
)以指示字符串的結尾。 您可以在數組中存儲ArrSz - 1
字符,並且ArrSz
字節存儲終止字符( '\o'
或0
)。
int RvsArr(char* Str, int end)
{
if (Str == 0 || end <= 1)
return 0;
int start = 0;
char tmp;
while(start < end)
{
tmp = Str[start];
Str[start] = Str[--end]; // pre decrement the counter to last char
Str[end] = tmp;
start++;
}
printf("%s", Str);
return 0;
}
或其他版本
int RvsArr(char* Str, int end)
{
if (Str == 0 || end <= 1)
return 0;
int start = 0;
int last = end - 1;
char tmp;
while(start < last)
{
tmp = Str[start];
Str[start] = Str[last];
Str[last] = tmp;
start++;
last--;
}
printf("%s", Str);
return 0;
}
主要 function 的一些變化是
int main()
{
int ArrSz;
printf("Please enter array size: ");
scanf("%i", &ArrSz);
char *Str;
Str = (char *)malloc(ArrSz * sizeof(char));
printf("Please enter your string: ");
scanf("%s", Str);
Str[ArrSz] = '\0'; // Here we have no control on how many characters are read, scan is a security vulnerability becuse of this
printf("Input=%s, len=%d\n", Str, strlen(Str));
RvsArr(Str, strlen(Str));
free(Str);
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.