[英]String copy function not copying string properly. What's wrong with my code?
我正在嘗試編寫一個函數,從字符串中刪除 whitesapces 並將其轉換為小寫。
我下面的代碼不返回任何內容。 為什么?
char *removeSpace(char *st);
int main(void){
char *x = "HeLLO WOrld ";
x = removeSpace(x);
printf("output: %s\n", x);
}
char *removeSpace(char *st)
{
int c = 0;
char *s = malloc(sizeof(strlen(st)+1));
for (int x = 0; x < strlen(st); x++)
{
if (st[x] != ' ')
{
s[x] = tolower(st[x]);
}
}
st= s;
st= s;
return st;
}
char *s = malloc(sizeof(strlen(st)+1));
你有幾個嵌套的表情,你的評論線程(我想這是50:50)躍升完全錯誤的方式。
strlen(st)
是字符串st
的字符數
strlen(st)+1
是為副本分配的正確字符數
......到目前為止看起來不錯!
sizeof(strlen(st)+1)
是表示該值類型所需的字節大小。 所以如果size_t
是一個 4 字節的unsigned int
,這個 sizeof 表達式就是4
。
此時字符串長度的值被丟棄。
現在,您想要為字符串分配足夠的字節,而不是足夠的字節來將字符串的長度保存為size_t
值。 只需完全刪除sizeof
。
哦,還有 - st = s
在這里沒有任何作用。 變量st
在函數內部是局部的,不會影響外部的任何東西。 返回s
就足夠了。
malloc 語句不必要地使用了 sizeof,如注釋中所述。 您在為新字符串分配字符時也有錯誤:
s[x] = tolower(st[x]);
您對新字符串 s 使用與舊字符串 st 相同的索引。 一旦刪除任何空格,這是不對的。 因此,例如,當您復制hello 時,索引 0 到 4 在兩個字符串之間排列,但隨后您跳過索引 5 處的空格,然后您想將 st[6] 處的w分配給 s[5]。 這意味着您需要一個單獨的索引來跟蹤您在目標字符串中的位置。 所以你需要像這樣的代碼,它清理 malloc(),添加缺少的頭文件,並為輸出字符串引入一個新的索引:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char *removeSpace(char *st);
int main(void){
char *x = "HeLLO WOrld ";
x = removeSpace(x);
printf("output: %s\n", x);
}
char *removeSpace(char *st)
{
size_t len = strlen(st);
int newStrIdx = 0;
char *s = malloc(len+1);
for (int x = 0; x < len; x++)
{
if (st[x] != ' ')
{
s[newStrIdx++] = tolower(st[x]);
}
}
s[newStrIdx] = '\0';
return s;
}
哦,你忘記了我在最后添加的空終止輸出字符串。
對於初學者來說,如果你想創建一個字符串的副本,那么函數聲明應該看起來像
char * removeSpace( const char *st);
即原始字符串在函數內未更改。
當你向函數傳遞一個字符串文字時
char *x = "HeLLO WOrld ";
x = removeSpace(x);
那么它確實可能不會在函數內改變。 任何更改字符串文字的嘗試都會導致未定義的行為。
malloc
調用中使用的表達式
sizeof(strlen(st)+1)
等價於表達式
sizeof( size_t )
由於函數strlen
具有返回類型size_t
。
所以這個表達式不會產生源字符串的長度。
此外,無需分配大小等於源字符串大小的字符串,因為目標字符串的字符數(由於刪除空格)可以比源字符串少得多。
if 語句中的賦值
if (st[x] != ' ')
{
s[x] = tolower(st[x]);
}
在表達式s[x]
使用無效索引。 因此,目標字符串將包含未初始化字符的間隙。
此外,終止零字符'\\0'
未附加到目標字符串
考慮到空白字符集包括其他字符,例如除空格字符' '
之外的制表符'\\t'
' '
。
該函數可以通過以下方式定義。
char * removeSpace( const char *st )
{
size_t n = 0;
for ( const char *src = st; *src; ++src )
{
if ( !isspace( ( unsigned char )*src ) ) ++src;
}
char *result = malloc( n + 1 );
result[n] = '\0';
for ( char *dsn = result; *st; ++st )
{
if ( !isspace( ( unsigned char )*st ) )
{
*dsn++ = tolower( ( unsigned char )*st );
}
}
return result;
}
該函數可以像這樣調用
char *st = "HeLLO WOrld ";
char *dsn = removeSpace( st );
puts( dsn );
free( dsn );
這是一個演示程序。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
char * removeSpace( const char *st )
{
size_t n = 0;
for ( const char *src = st; *src; ++src )
{
if ( !isspace( ( unsigned char )*src ) ) ++src;
}
char *result = malloc( n + 1 );
result[n] = '\0';
for ( char *dsn = result; *st; ++st )
{
if ( !isspace( ( unsigned char )*st ) )
{
*dsn++ = tolower( ( unsigned char )*st );
}
}
return result;
}
int main(void)
{
char *st = "HeLLO WOrld ";
char *dsn = removeSpace( st );
puts( dsn );
free( dsn );
return 0;
}
它的輸出是
helloworld
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.