簡體   English   中英

覆蓋未知長度的字符串以解決小寫問題

[英]Coverting an unknown length string to lower case issues

因此,我對C不太滿意,但是我正在設計一個GLUT應用程序,該應用程序讀取的文件不區分大小寫。 為了更容易,我想將字符串轉換為所有小寫字母。 我做了一個函數makeLower,該函數正在修改通過引用傳遞的變量。

我在makeLower方法中有一個While循環,該循環似乎可以通過while循環的第一次迭代的一部分,然后使EXE崩潰。 任何提示都很好,謝謝!

輸出:

C:\Users\Mark\Documents\Visual Studio 2010\Projects\Project 1\Debug>"Project 1.e
xe" ez.txt

Line is #draw a diamond ring

Character is #

然后錯誤“項目1.exe已停止工作”

碼:

void makeLower(char *input[]){
    int i = 0;
    printf("Line is %s\n", *input);

    while(input[i] != "\0"){
        printf("Character is %c\n", *input[i]); 
        if(*input[i] >= 'A' && *input[i] <= 'Z'){
            *input[i] = tolower(*input[i]);
        }
        i++;
    }

}

int main(int argc, char *argv[]) {
    FILE *file = fopen(argv[1], "r");
    char linebyline [50], *lineStr = linebyline;
    char test;

    glutInit(&argc, argv);

    while(!feof(file) && file != NULL){
        fgets(lineStr , 100, file);
        makeLower(&lineStr);
        printf("%s",lineStr);

        //directFile();

    }
    fclose(file);


    glutMainLoop();
}

我現在看到了更多問題,因此我將評論擴展到一個答案:

您分配了一個由50個字符組成的數組,但告訴fgets最多獲取100個字符,這可能是致命的,因為fgets會覆蓋不在字符串中的內存。

將C字符串傳遞給函數時,不必將指針的地址傳遞給字符串( &lineStr ),實際的指針或數組都可以。 這意味着您可以將makeLower函數更改為void makeLower(char *input)void makeLower(char input[]) 現在, makeLower的參數聲明為數組或char指針,而不是char數組的指針。

在上面我提出的新makeLower ,您可以將單個字符作為數組( input[i] )或作為指針加上偏移量( *(input + i) ,就像我在評論中說的那樣,最后一個版本是如果您使用第一個,則編譯器可能會創建,但是第一個更易讀,所以我建議這樣做。

同樣在makeLower您與"\\0"進行比較, "\\0"是字符串而不是字符。 實際上這幾乎是正確的:您應該使用input[i] != '\\0'

最后,這就是我的實現方式:

void makeLower(char *input)
{
    while (*input != '\0')  /* "while (*input)" would also work */
    {
        *input = tolower(*input);
        input++;
    }
}

有關該功能的一些解釋:

  • 可以將所有char數組轉換為char指針,但不能相反。 傳遞char指針實際上是傳遞字符串的最常用方法,正如您從所有接受字符串的標准函數(如strlenstrcpy )中所看到的那樣。
  • 表達式*input 取消引用 (即獲取指針指向的值)字符串。 它與*(input + 0) ,因此獲取字符串中第一個字符的值。
  • 雖然字符串中的第一個字符不是'\\0' (從技術上來說是正常的零),我們將循環播放。
  • 獲取字符串的第一個字符,並將其傳遞給tolower函數。 無論字符是什么,這都將起作用, tolower只會將大寫字符變為小寫,所有其他字符將被返回。
  • 結果tolower復制的第一個字符。 之所以可行,是因為必須在分配之前執行分配的右側,因此不會有任何錯誤或問題。
  • 最后,我們將指針增加一個。 這將使input指向字符串中的下一個字符。 這是可行的,因為input是局部變量,因此對指針的操作不會影響調用函數中的任何內容。

現在可以這樣調用該函數:

char input[100];
fgets(input, sizeof(input), stdin);
printf("before: \"%s\"\n", input);
makeLower(input);
printf("after : \"%s\"\n", input);

您是否嘗試了while(* input [i]!=“ \\ 0”)而不是您擁有的東西? 由於某種原因,您似乎將指向char(* input [])和&lineStr的指針傳遞給函數,因此在檢查字符串終止符“ \\ 0”時,應兩次取消引用。...

只是一個想法,希望對您有所幫助

我認為問題是您不希望該字符串等於'\\ 0'。 因此,您可能會超出范圍,這很可能是您不知道字符串的長度。

據我了解,可以將'\\ 0'傳遞給tolower() 這是有效的unsigned char值,並且tolower()僅在無法進行任何轉換tolower()返回輸入字符。

因此,可以將循環簡寫為:

while(input[i] = tolower(input[i]))
  ++i;

這會再調用一次tolower() ,但它更短,並且(imo)很清楚。 只是想提一下它。

暫無
暫無

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

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