我想創建一個函式,它可以在不使用<string.h>庫的情況下替換兩個字串。為了實作這一點,我使用了 6 個手動撰寫的函式,它們共同完成了這個任務。我對這段代碼有一個小問題,這不會檢查將被替換的字串是否是完全等于替換字串的單詞。
例如:
char s[] = "Why is ostring in C so hard",
change_what[] = "string",
into_what[] = "pointers";
輸出應該是:
"Why is ostring in C so hard"
因為"ostring"不完全等于"string"。
我的輸出是:
"Why are opointers in C so hard"
代碼:
#include <stdio.h>
int compare(char *x, char *y)
{
while (*x != '\0' || *y != '\0')
{
if (*x == *y)
{
x ;
y ;
}
// if they are not equal
else if ((*x == '\0' && *y != '\0') || (*x != '\0' && *y == '\0') ||
*x != *y)
{
return 0;
}
}
return 1;
}
int lenght(char *a)
{
char *b;
for (b = a; *a; a )
;
return a - b;
}
char *substring(char *main_string, char *substring) {
while (*main_string != '\0') {
char *p = main_string;
char *q = substring;
while (*p == *q ) {
if (*p == ' ' || *p == '\0')
if (*q == '\0') {
return main_string;
}
}
main_string ;
}
return NULL;
}
void replace_string_add(char *s, char *change_what, char *into_what,
int shift)
{
char *i_pointer = into_what;
char *c_pointer = change_what;
char *position = substring(s, change_what);
while (position != NULL)
{
char *end = position;
while (*end != '\0')
{
end ;
}
while (end > position)
{
*(end shift) = *end;
end--;
}
while (*into_what != '\0')
{
*position = *into_what ;
}
position = substring(s, change_what);
into_what = i_pointer;
change_what = c_pointer;
}
}
void replace_string_remove(char *s, char *change_what, char *into_what,
int shift)
{
char *i_pointer = into_what;
char *c_pointer = change_what;
char *position = substring(s, change_what);
while (position != NULL)
{
char *temp = position;
while (*(temp shift) != '\0')
{
*temp = *(temp shift);
temp ;
}
*temp = '\0';
while (*into_what != '\0')
{
*position = *into_what ;
}
position = substring(s, change_what);
into_what = i_pointer;
change_what = c_pointer;
}
}
void replace_string(char *s, char *change_what, char *into_what)
{
int shift = lenght(into_what) - lenght(change_what);
if (compare(change_what, into_what) == 0)
{
if (shift >= 0)
{
replace_string_add(s, change_what, into_what, shift);
}
else
{
replace_string_remove(s, change_what, into_what, -shift);
}
}
}
int main()
{
char s[] = "Why is ostring in C so hard",
change_what[] = "string",
into_what[] = "pointers";
replace_string(s, change_what, into_what);
printf("\"%s\"", s);
return 0;
}
如果字串是"Why is strings in C so hard"程式將正常作業,因為它會檢查最后一個字符是否為' '或'\0'。
"Why is ostring in C so hard"行不通,因為它不檢查第一個字符。你能幫我修改這段代碼來檢查第一個字符嗎?
- 注意:輔助字串和動態分配是不允許的
uj5u.com熱心網友回復:
您的程式有多個問題:
函式中有很多冗余代碼
compare。您可以將其簡化為:int compare(const char *x, const char *y) { while (*x != '\0' || *y != '\0') { if (*x == *y) { x ; y ; } else { return 0; } } return 1; }甚至更進一步:
int compare(const char *x, const char *y) { while (*x == *y ) { if (x[-1] == '\0') return 1; } return 0; }該
lenght函式應命名lengthsubstring檢查子字串結束后的空格,但不檢查開始前的空格。如果子字串與結尾匹配,它也有未定義的行為,main_string因為將訪問空終止符之外的字符。這是修改后的版本:char *substring(char *main_string, const char *substring) { char *p = main_string; char last = ' '; while (*p != '\0') { if (last == ' ') { size_t i = 0; while (substring[i] != '\0' && p[i] == substring[i]) { i ; } if (substring[i] == '\0' && (p[i] == ' ' || p[i] == '\0')) { return p; } } last = *p ; } return NULL; }in
replace_string_add和replace_string_remove,是無用的,使用復制替換比修改和恢復它c_pointer更容易混淆。i_pointerinto_what
另請注意,引數必須有足夠的空間用于替換,如果字串為main_string,則示例中的情況并非如此。change_what"ostring"
這是修改后的版本:
#include <stdio.h>
int compare(const char *x, const char *y) {
while (*x == *y ) {
if (x[-1] == '\0')
return 1;
}
return 0;
}
int length(const char *a) {
const char *b;
for (b = a; *a; a )
continue;
return a - b;
}
char *substring(char *main_string, const char *substring, int len) {
char *p = main_string;
char last = ' ';
while (*p != '\0') {
if (last == ' ') {
int i = 0;
while (i < len && p[i] == substring[i]) {
i ;
}
if (i == len && (p[i] == ' ' || p[i] == '\0')) {
return p;
}
}
last = *p ;
}
return NULL;
}
char *replace_string(char *s, const char *change_what, const char *into_what) {
int what_len = length(change_what);
int into_len = length(into_what);
int shift = into_len - what_len;
int i;
char *pos = s;
if (shift == 0 && compare(change_what, into_what))
return s;
while (*pos && (pos = substring(pos, change_what, what_len)) != NULL) {
if (shift > 0) {
for (i = length(pos); i >= what_len; i--) {
pos[i shift] = pos[i];
}
} else
if (shift < 0) {
for (i = into_len; ((pos[i] = pos[i - shift]) != '\0'; i ) {
continue;
}
}
for (i = 0; i < into_len; i ) {
*pos = into_what[i];
}
if (*pos == ' ') {
pos ;
}
}
return s;
}
int main() {
char s[100] = "Why is ostring in C so hard";
printf("\"%s\"\n", replace_string(s, "string", "pointer"));
printf("\"%s\"\n", replace_string(s, "ostring", "pointers"));
printf("\"%s\"\n", replace_string(s, "is", "are"));
printf("\"%s\"\n", replace_string(s, "hard", "cool"));
printf("\"%s\"\n", replace_string(s, "pointers", "strings"));
printf("\"%s\"\n", replace_string(s, "in C", ""));
printf("\"%s\"\n", replace_string(s, "", "in C not"));
printf("\"%s\"\n", replace_string(s, "", ""));
return 0;
}
輸出:
"Why is ostring in C so hard"
"Why is pointers in C so hard"
"Why are pointers in C so hard"
"Why are pointers in C so cool"
"Why are strings in C so cool"
"Why are strings so cool"
"Why are strings in C not so cool"
"Why are strings in C not so cool"
uj5u.com熱心網友回復:
好的,我認為為此使用字串標記器更容易。以下代碼首先將 s 復制到 s2 中,然后在每個空格處放置一個 '\0' 并跟蹤有多少單詞。第一個 for 回圈。然后清除 s 并回圈遍歷 s2 在每個 '\0' 標記處停止并檢查每個單詞是否等于您的替換單詞。如果匹配,則復制回替換詞,否則復制原始詞。
#include <stdio.h>
static void cat(char *d, char *s)
{
char *p;
for (p = d; *p; p );
for (char *p2 = s; *p2;)
*p = *p2 ;
*p = 0;
}
static int cmp(char *s1, char *s2)
{
char *p1 = s1, *p2 = s2;
while (*p1 && *p2 && *p1 == *p2)
{
p1 ;
p2 ;
}
if (*p1 == 0 && *p2 == 0) return 0;
return -1;
}
int main()
{
char s[100]="Why are strings in C so hard",change_what[]="strings", into_what[]="pointers";
char s2[100];
for (char *p = s, *p2 = s2; *p2=*p; p , p2 );
int countwords = 0;
for (char *p = s2; *p; p )
if (*p == ' ') { *p = '\0'; countwords ; }
int current = 0;
char *s3 = s2;
*s = '\0';
while (current <= countwords)
{
char *p = s3;
for (; *p; p );
if (cmp(s3, change_what) == 0)
cat(s, into_what);
else
cat(s, s3);
cat(s, " ");
s3 = p 1;
current ;
}
printf("%s\n", s);
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/426982.html
上一篇:如何從開頭提取子字串到一個字符?
下一篇:僅從字串中列印非全大寫“單詞”?
