簡體   English   中英

為什么指針算術在char *函數中不起作用

[英]Why doesn't pointer arithmetic work in char* functions

訊息:

/usr/local/webide/runners/c_runner.sh: line 54: 20533 Segmentation fault
nice -n 10 valgrind --leak-check=full --log-file="$valgrindout" "$exefile"

我不明白為什么我的函數類型不是void時不能使用指針算術。 看一下這個例子:

假設我必須編寫一個函數來“擦除”字符串中第一個單詞之前的所有空格。 例如,如果我們有一個char數組:

"    Hi everyone"

修改功能后,應該會產生"Hi everyone"

這是我的代碼,當我有char* EraseWSbeforethefirstword()時,它可以正常工作
void EraseWSbeforethefirstword

當函數返回對象char*它甚至無法編譯。

char* EraseWSbeforethefirstword(char *s) {
    char *p = s, *q = s;

    if (*p == ' ') { /*first let's see if I have a string that begins with a space */
        while (*p == ' ') {
            p++;
        } /*moving forward to the first non-space character*/

        while (*p!= '\0') {
            *q = *p; 
            p++; 
            q++;
        } /*copying the text*/

        *q = '\0'; /*If I had n spaces at the beginning the new string has n characters less */
    }
    return s;
} 

這是一個函數實現,可以根據需要具有返回類型char *

#include <stdio.h>

char *  EraseWSbeforethefirstword( char *s ) 
{
    if ( *s == ' ' || *s == '\t' )
    {
        char *p = s, *q = s;

        while ( *p == ' ' || *p == '\t' ) ++p;

        while ( ( *q++ = *p++ ) );
    }

    return s;
}

int main(void) 
{
    char s[] = "\t Hello World";

    printf( "\"%s\"\n", s );

    printf( "\"%s\"\n", EraseWSbeforethefirstword( s ) );

    return 0;
}

程序輸出為

"    Hello World"
"Hello World"

請注意,您不得修改字符串文字。 因此,如果不是數組,程序將具有未定義的行為

char s[] = "\t Hello World";

將聲明一個指向字符串文字的指針

char *s = "\t Hello World";

如果您希望函數可以處理字符串文字,則函數必須動態分配新數組並返回指向其第一個元素的指針。

如果您可能不使用標准的C字符串函數,則該函數可以如下所示

#include <stdio.h>
#include <stdlib.h>

char *  EraseWSbeforethefirstword( const char *s )
{
    size_t blanks = 0;

    while ( s[blanks] == ' ' || s[blanks] == '\t' ) ++blanks;

    size_t length = 0;

    while ( s[length + blanks] != '\0' ) ++length;

    char *p = malloc( length + 1 );

    if ( p != NULL )
    {
        size_t i = 0;
        while ( ( p[i] = s[i + blanks] ) != '\0' ) ++i;
    }

    return p;
}

int main(void) 
{
    char *s= "\t Hello World";

    printf( "\"%s\"\n", s );

    char *p = EraseWSbeforethefirstword( s );

    if ( p ) printf( "\"%s\"\n", p );

    free( p );

    return 0;
}

暫無
暫無

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

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