簡體   English   中英

C中的strlen函數

[英]strlen function in c

這聽起來可能有些愚蠢,但卻感到困惑。 我知道strlen()會返回c中字符數組的大小。 但是指向字符的指針發生了一些變化。 這是我的代碼:

void xyz(char *number)
{
    int i = 0;
    int length = strlen(number) - 2;
    while(i <= length)
    {
        printf("Number[]: %c",number[i]);
        i++;
    }
}

這會打印出我輸入的完整數字(例如:12345),但是如果我刪除了-2,結果將是不同的。 誰能告訴我我想念什么?

您很有可能會對使用fgets或類似輸入函數獲得的字符串執行此操作。 在這種情況下,很可能換行符仍在末尾。

如果您將代碼臨時更改為:

void xyz (char *number) {
    int i = 0, length = strlen (number);
    while (i < length)
        printf ("Number[%d]: %c (%d)", i, number[i], number[i]);
        i++;
    }
}

還應該顯示所有字符的數字代碼。

在您的函數中編碼類似這樣的東西- 2的問題是它不適用於:

xyz ("123");

因為它將提前停止,所以只打印12 調用方應使用有效數據進行調用,這意味着在調用前應將其值調整為數字字符串。


您可以在以下程序中看到這種情況:

#include <stdio.h>
#include <string.h>

void xyz (char *number) {
    int i = 0, length = strlen(number) - 2;
    while(i <= length)
    {
        printf("Number[%d]: %c (%d)\n",i, number[i], number[i]);
        i++;
    }
    puts ("===");
}

void xyz2 (char *number) {
    int i = 0, length = strlen(number);
    while(i < length)
    {
        printf("Number[%d]: %c (%d)\n",i, number[i], number[i]);
        i++;
    }
    puts ("===");
}

int main (void) {
    char buff[100];
    printf ("Enter number: ");
    fgets (buff, sizeof (buff), stdin);
    xyz (buff);
    xyz ("12345");
    xyz2 (buff);
    xyz2 ("12345");
    return 0;
}

如果輸入98765 ,則此輸出的(注釋)為:

Enter number: 98765
Number[0]: 9 (57)
Number[1]: 8 (56)
Number[2]: 7 (55)  # Your adjustment works here because of the newline.
Number[3]: 6 (54)
Number[4]: 5 (53)
===
Number[0]: 1 (49)
Number[1]: 2 (50)
Number[2]: 3 (51)  # But not here, since it skips last character.
Number[3]: 4 (52)
===
Number[0]: 9 (57)
Number[1]: 8 (56)
Number[2]: 7 (55)  # Here you can see the newline (code 10).
Number[3]: 6 (54)
Number[4]: 5 (53)
Number[5]:
 (10)
===
Number[0]: 1 (49)
Number[1]: 2 (50)
Number[2]: 3 (51)  # And proper numeric strings work okay.
Number[3]: 4 (52)
Number[4]: 5 (53)
===

如果您正在尋找可以解決此問題的強大的用戶輸入函數(並且避免了諸如unbounded scanf("%s")這樣的危險事件並gets )的信息,那么我會在SO的其他地方(實際上是在這里 )兵工廠。

檢查是否適合您-

void xyz(char *number)
{
    int length = strlen(number);

    while(i < length)
    {
        printf("Number[]: %c",number[i]);
        i++;
    }
}

和此函數(如果調用為

xyz("1234");

應該打印出來:

Number[]: 1
Number[]: 2
Number[]: 3
Number[]: 4

那是您真正想要的嗎? 如果是這樣,那么讓我指出2個錯誤。

1)“ i”未初始化。 這更多是一個良好實踐的問題。 顯式初始化循環控制變量(在這種情況下為零),只是不要假定已對其進行設置。 2)使用“ <=”的while循環條件應該多運行1個周期。

請記住,數組從索引'0'(零)開始,大小為10的數組具有從0到9的有效索引,並且C lang使用空字符('\\ 0')來終止字符串。 因此,您的“ 1234”實際上存儲為:

字符串[0] ='1'字符串[1] ='2'字符串[2] ='3'字符串[3] ='4'字符串[4] ='\\ 0'(<= NULL)

因此,如果循環計數器(控制變量)在循環開始時i = 0,則對於第一次迭代,您選擇字符串[0],對於第二次迭代(當i = 1時),您選擇字符串[1] ...這樣,循環應該只運行4次,即當i == 4(即loopcounter <字符串長度)時,您必須停止並退出循環。

希望這能消除您的疑問和幫助。 如果是這樣,請不要忘記接受答案。

我這樣做了,並收到了這樣的輸出:

strlen(number)-2刪除最后一個null和最后一個包含4的字符。

輸出:

 Number[]: 1 Number[]: 2 Number[]: 3 

碼:

int main()
{
    xyz("1234");
}
void xyz(char *number)
{
    int i=0;
    int length = strlen(number) - 2;
    while(i <= length)
    {
        printf("\nNumber[]: %c",number[i]);
        i++;
    }
}

它有效,並且您必須初始化i

strlen()返回字符串的長度,但是C數組(因此字符串)的索引為零。 因此,您要增加直到達到strlen() - 1 您可以通過從長度中減去一個並使用小於或等於測試- <= -在while循環中執行此操作,也可以只使用strlen()並繼續循環,只要您的計數器嚴格小於比你的長度。

可能的錯誤來源:

  1. 如果不初始化i ,則賠率就是它從該內存位置先前所獲得的值將大大超過長度。 因此,您的while條件將在第一次執行時失敗。
  2. 如果超過字符串的末尾,您將在字符串的末尾看到一個NULL字符- '\\0' ,並在該字符串之后進行隨機垃圾回收。

我的猜測是您正在使用fgets讀取某些輸入。 在這種情況下,當您輸入“ 12345”並按Enter鍵時,您的緩沖區將如下所示:

{'1','2','3','4','5','\\ n','\\ 0'}

如您所見,我們不需要2個字符。 因此,我們可以做的就是從緩沖區末尾截斷換行符char '\\n'

因此,假設這是我們在輸入中讀取的方式:

int main(void)
{
   char buff[20];
   fgets(buff, 20, stdin);

   buff[strlen(buff) - 1] = '\0'; /* remove the '\n' */
   xyz(buff);
}

現在,煩人的換行符將不再存在,而看起來像空的循環最后一次迭代輸出將消失。 現在為xyz

void xyz(char *number)
{
   int i, length = strlen(number);
   for (i = 0; i < length; i++)
      printf("Number[%d]: %c", i, number[i]);
}

請注意,我們現在從長度中減去任何東西。 這有兩個原因:第一個是我在上面提到的換行符,第二個是因為條件現在是< length ,而不是<= length (我在上面的評論中提到過)。 <= length表示我們將在字符串末尾(“ \\ 0”字符)之后讀取1,因為第一個索引是number[0] ,最后一個number[length - 1]

您實際上必須要做的是:

int length = strlen(number) - 1;

獲得正確的輸出。

此外,您還必須記住,您正在將字符數組傳遞給xyz函數。 因此,如果您執行以下操作:

xyz("12345")

您的長度為5個字節。 在while循環中,for number[i]索引實際上從0開始,而不是1,因此您需要減去1以獲得正確的結果,因此使用int length = strlen(number) - 1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM