簡體   English   中英

為什么strlen()不代表我的字符串的實際長度?

[英]Why does strlen() not represent the actual length of my string?

基本上,我有一個由多個單詞組成的字符串,例如: "Hello world test"
如果我嘗試使用這樣的結構進行打印

printf("%s", string);

或像這樣

for (int i = 0; i < strlen(string); ++i) {
    printf("%c", string[i];
}

我總是將其作為輸出: Hello world ,我也得到了11而不是16的驚喜。

如果我嘗試使用以前對字符串中的單個字符進行計數的int計數器打印出相同的字符串,

for (int i = 0; i < counter; ++i) {
    printf("%c", string[i];
}

我實際上得到了正確的輸出Hello world test ,這導致我們相信在字符串中正確分配了元素,但是由於某些原因,%s和strlen只是忽略了最后一個空格之后的元素。

為什么會這樣? 到底是怎么回事? 我怎樣才能解決這個問題?

編輯:

要求的實際代碼:

#include <stdio.h>
#include <string.h>
typedef int BOOL;
#define TRUE 1
#define FALSE 0


int main() {
    char sentence[64] = " ", reversal[64] = " ", reversal_copy[64] = " ";
    int index = 0, counter = 0;
    BOOL reset = TRUE, last_cycle = FALSE;

    printf("Enter a sentence: ");
    for (int i = 0; sentence[strlen(sentence) - 1] != '\n'; i++) {
        scanf("%c", &sentence[i]);
    }

    /* Copies the input in a string reversing it */
    for (int h = strlen(sentence) - 2, k = 0; h >= 0; h--, k++) {
        reversal[k] = sentence[h];
    }

    /* Detects the first character of a word and the last character of the same word before a space,
    switching the first char with the last, the second with the pre-last and so on*/
    for (int i = 0; i < strlen(reversal); i++) {
        if (reset == TRUE) {
            index = i;
            reset = FALSE;
        }
        if (i == strlen(reversal) - 1) {
            last_cycle = TRUE;
            counter++;
        }
        if (reversal[i] != ' ') {
            counter++;
            if (last_cycle == TRUE) {
                goto reversing;
            }
        }
        else {
        reversing:
            for (int h = index, z = counter; h < counter; h++, z--) {
                reversal_copy[h] = reversal[z - 1];
                reversal_copy[z - 1] = reversal[h];
            }
            if (last_cycle == FALSE) {
                reversal_copy[i] = ' ';
            }
            reset = TRUE;
            counter++;
        }
    }
    printf("%lu ", strlen(reversal_copy));
    for (int i = 0; i < counter; i++) {
        printf("%c", reversal_copy[i]);
    }
    printf("%s\n\n", reversal_copy);

    return 0;
}

如果strlen()返回11,則在世界“世界”之后您有一個\\0字符。

strlenprintf都使用0終止符來確定“字符串是什么”,因此它們的行為相同也就不足為奇了。

如果沒有最小,完整和可驗證的示例 ,這很難回答,但我將解釋您所觀察到的行為的最可能原因。

雙方printf%s格式說明和strlen給你空值終止字符串的長度由相關參數指向。 如果他們打印/報告的長度為11,但是遍歷整個char數組且硬編碼值為16,則輸出為“ hello world test”,則world之后的字符顯然是空字符'\\ 0 '。

嘗試以輸入“ A”為例運行您的程序-看看哪怕是一個單詞也有問題。

當您倒數最后一個字時出現問題。 您在其末尾放置了'\\0' 它可能與last_cycle邏輯周圍的特殊大小寫和goto有關,這很難遵循。

我認為這可能與以下事實有關:在該代碼路徑中有兩個counter++

考慮使用一些函數使代碼更簡潔:

len = strlen(reversal);
for (start=0; start<len; start++) {
   end = find_space_or_null(reversal, start);
   if (end > start) {
    reverse_chars(reversal, start, end-1);
    start = end;
   }
}

該程序接受用戶輸入的字符串,例如“天藍色”,並打印出“天藍色”

對於strtok()這是一項完美的工作:

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

enum { MAX_LINE = 120 };

int main()
{
    char buffer[MAX_LINE];
    fgets(buffer, MAX_LINE, stdin);

    size_t length = strlen(buffer);
    if (length && buffer[length - 1] == '\n')  // get rid of the newline
        buffer[--length] = '\0';

    char *tokens[MAX_LINE] = { 0 };  // there can't be more than 60 tokens, but hey
    if ((tokens[0] = strtok(buffer, " ")) == NULL)  // no tokens? nothing to do.
        return 0;

    size_t i = 1;
    for (; tokens[i - 1] && i < sizeof(tokens); ++i)
        tokens[i] = strtok(NULL, " ");  // tokenize the buffer

    --i;  // the very last was NULL anyway.
    while (--i)  // print it reverse
        printf("%s ", tokens[i]);
    puts(buffer);
}

樣本輸出:

The quick brown fox jumps over the lazy dog
dog lazy the over jumps fox brown quick The

暫無
暫無

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

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