[英]Simple question on printf and C. Printing characters of a string one by one
[英]delete leading characters before a string in C (concept question)
我正在學習 C,處理字符串和指針。 練習要求刪除字符串前的所有前導字符(在本例中為“X”)。 被調用的 function 必須接受一個字符串,即一個指向 char 的指針。 我通過搜索找到了多種執行此操作的方法,但我不明白為什么以下代碼不起作用......我缺少什么概念?
//delete all leading X characters by passing pointer to a string
#include <stdio.h>
#include <string.h>
void delChar(char* str)
{
char* walker; //declare pointer
walker = str; //point to beginning of passed string
while(*walker == 'X') walker++; //move pointer past amy leading 'X'
printf("\nwalker string is now: %s", walker); //prints "Test" as expected
str = walker; //set str pointer to walker
printf("\nstr string is now: %s", str); //prints "Test" as expected
return;
}
int main()
{
char* myStr = "XXXXXXXXXXXXTest";
printf("Before function call: %s", myStr); //prints "XXXXXXXXXXXXTest" as expected
delChar(myStr); //pass pointer to the string
printf("\nAfter function call: %s", myStr); //WHY DOES THIS print "XXXXXXXXXXXXTest" ?
return 0;
}
有多種方法可以從字符串中刪除字符,但不清楚您想要哪種。
C、memory內容不能“刪除”。 Memory 由字節組成,字節保存值。 當我們有一個字符串的時候,它存在於memory的某個地方,而這個字符串的字節是不能把go弄走的。
從字符串中刪除字符的三種方法是:
以下是示例實現:
#include <stdio.h>
/* Deletion method 0: Find the first character that is not an "X" and
return its address.
*/
static char *DeleteMethod0(char *string)
{
for (char *p = string; ; ++p)
if (*p != 'X')
return p;
}
// Deletion method 1: Update the pointer to the start of the string.
static void DeleteMethod1(char **string)
{
while (**string == 'X')
++*string;
}
// Deletion method 2: Move characters.
static void DeleteMethod2(char *string)
{
// Find the point where we stop deleting.
char *source = string;
while (*source == 'X')
++source;
// Copy the undeleted part of the string to the start.
while (*source)
*string++ = *source++;
*string = '\0';
}
int main(void)
{
char *string = "XXXXXXXXXXXXTest";
char buffer[] = "XXXXXXXXXXXXTest";
printf("The string is %s.\n", string);
printf("The buffer contains %s.\n", buffer);
char *after = DeleteMethod0(string);
printf("The string after deletion by getting new address %s.\n", after);
DeleteMethod1(&string);
printf("The string after deletion by updating the pointer is %s.\n", string);
DeleteMethod2(buffer);
printf("The buffer after deletion by moving characters is %s.\n", buffer);
}
另一種選擇是制作字符串所需部分的新副本,在 memory 中,由調用者提供或由刪除例程分配。
對於初學者,function 應該聲明為
char * delChar( char *str );
function參數str
是function的局部變量。所以這個賦值
str = walker;
不改變 main 中聲明的指針myStr
。 此指針按值傳遞給 function。 即 function 處理指針的副本。 並且賦值不會改變原始指針myStr
。 它僅更改由指針myStr
的值的副本初始化的局部變量str
。
您也不能更改字符串文字。 任何更改字符串文字的嘗試都會導致未定義的行為。 但是您確實需要更改傳遞的字符串,至少要遵循您的分配
刪除 C 中字符串前的前導字符
也就是說,任務不是找到指向第一個不等於'X'
的字符的指針。 您需要從字符串中刪除等於'X'
前導字符。
在 main 中,您需要聲明一個字符數組而不是一個指向字符串文字的指針,例如
char myStr[] = "XXXXXXXXXXXXTest";
function本身可以通過以下方式定義
char * delChar( char *str )
{
char *walker = str;
while ( *walker == 'X' ) ++walker;
if ( walker != str ) memmove( str, walker, strlen( str ) + 1 - ( walker - str ) );
return str;
}
主要是寫就足夠了
printf("After function call: %s\n", delChar( myStr ) );
這是一個演示程序
#include <stdio.h>
#include <string.h>
char * delChar( char *str )
{
char *walker = str;
while (*walker == 'X') ++walker;
if (walker != str) memmove( str, walker, strlen( str ) + 1 - ( walker - str ) );
return str;
}
int main( void )
{
char myStr[] = "XXXXXXXXXXXXTest";
printf( "Before function call: %s\n", myStr );
printf( "After function call: %s\n", delChar( myStr ) );
}
程序 output 是
Before function call: XXXXXXXXXXXXTest
After function call: Test
function 將更靈活,如果聲明第二個參數將指定應從字符串開頭刪除的字符。 例如
char * delChar( char *str, char c )
{
if ( c != '\0' )
{
char *walker = str;
while (*walker == c) ++walker;
if (walker != str) memmove( str, walker, strlen( str ) + 1 - ( walker - str ) );
}
return str;
}
在這種情況下,function 被稱為
printf( "After function call: %s\n", delChar( myStr, 'X'));
感謝您的周到回復和評論。 我推斷這基本上是關於指針的問題; 那是。 無需從 function 調用返回指針即可修改字符串。 為了那些可能正在學習的人的利益,我簡化了示例代碼問題,並附有評論(見下文)。 如果我不在基地,請告訴我...
#include <stdio.h>
#include <stdlib.h>
void func(char** str) //note POINTER-TO-POINTER parameter!
{
printf("\nintial func str: %s", *str); //note dereference before str; prints "FULL TEXT"
*str += 5; //increment pointer five spaces to right to modify the string
printf("\nafter func str: %s", *str); //note dereference before str; prints "TEXT"
}
int main()
{
char* myStr = "FULL TEXT"; //need to initialize string with pointer variable
//char myStr[] = "FULL TEXT"; //initializing string as array will not work for this example!
printf("\n...before MAIN func call: %s", myStr); //prints "FULL TEXT"
/*pass ADDRESS of pointer variable instead of pointer variable itself, i.e. func
parameter needs to be a pointer-to-a-pointer...this is essentially passing by REFERENCE
instead of by VALUE (where a copy would get clobbered when returning to main)*/
func(&myStr); //note ADDRESS symbol, i.e. address of pointer variable
printf("\n...after MAIN func call: %s", myStr); //prints "TEXT", modified string remains after func call
return 0;
}
function 中的 str 變量delChar
將在您傳遞的堆棧和存儲地址上創建,並在 function 返回時銷毀
void delChar(char* str) // str variable will created over stack and store address you have passed and will be destroyed when function returns
{
char* walker; //declare pointer
walker = str; //point to beginning of passed string
while(*walker == 'X') walker++; //move pointer past amy leading 'X'
printf("\nwalker string is now: %s", walker); //prints "Test" as expected
str = walker; //set str pointer to walker
printf("\nstr string is now: %s", str); //prints "Test" as expected
return;
}
在 main 中返回 str 后仍將指向字符串的開頭。
你需要返回地址和商店
您可以使用計數器跟蹤計數並返回計數,如下所示
#include<stdio.h>
int delChar(char* str)
{
int count = 0;
while(*str++ == 'X')
count++; // increment the count when x found
printf("\nwalker string is now: %s", str+count);
return count;
}
int main()
{
char* myStr = "XXXXXXXXXXXXTest";
int count;
printf("Before function call: %s", myStr);
count = delChar(myStr);
printf("\nAfter function call: %s", myStr+count);
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.