簡體   English   中英

傳遞 function 中的地址后指向垃圾值的指針

[英]Pointer pointing to garbage value after passing the address in a function

兩個指針 keyClickPtr 和 secondPtr 總是擁有一個垃圾值,而不是擁有來自 keyPress function 的 keyClick 和 second 變量的值。 我正在嘗試檢查除了用戶在允許的字符 C、P 或 E 之后輸入的換行符之外是否有任何尾隨字符。我輸入的輸入示例是“我們”。

主要的:

#include <stdio.h>
void keyPress(void);
void trCharsInKeyPress(char* keyClickPtr, char* secondPtr);
    
void main(void) {
    keyPress();
    return 0;
    }

Function:

  void keyPress(void) {
    
    char keyClick = '\0', second = '\0';
    
    printf("Enter C, P or E: ");
    scanf("%c%c", &keyClick, &second);
    
    if (second != '\n') trCharsInKeyPress(&keyClick, &second);

    return 0;
}

Function:

void trCharsInKeyPress(char* keyClickPtr, char* secondPtr) //issue here 
    {
        while (*secondPtr != '\n') {
    
            printf("No trailing characters allowed. Press try again: ");
            scanf("%c%c", keyClickPtr, secondPtr);
        }
return 0;
    }

試試這個:

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

void keyPress(void);

int main(void)
{
    keyPress();
    return 0;
}


void keyPress(void)
{
    char userInput[100];
    bool valid = false;

    while (!valid)
    {
        printf("Enter C, P or E: ");                // query for user input
        fgets(userInput, sizeof(userInput), stdin); // get the input
        userInput[strlen(userInput) - 1] = '\0';    // removes the \n at end when the user press enter

        if(strlen(userInput) != 1){
            printf("No trailing characters allowed. Press try again.\n");
        } else{
            if (userInput[0] == 'C' || userInput[0] == 'P' || userInput[0] == 'E' || userInput[0] =='c'||userInput[0] =='p'|| userInput[0] =='e')
                valid = true;
            else
                printf("Must be C, P or E. Press try again.\n");
        }
    }
}

您的原始代碼似乎不需要在任何地方返回該值,但如果您只是創建一個指針以傳回主代碼或留下評論並編輯代碼以向您展示如何將值帶回主代碼。

您嘗試使用格式化輸入function 使用戶輸入變得非常復雜(並且由於不處理"%c" (和"%[..]""%n" )不丟棄前導空格這一事實,進一步的復雜化很重要. 對於嘗試使用scanf()進行用戶輸入的新 C 程序員來說,這只是眾多陷阱之一。

相反,您應該使用面向行的輸入 function,例如fgets()或 POSIX getline()來讀取和使用整行用戶輸入。 使用足夠大的緩沖區(或getline()為您動態分配),無論用戶輸入多少個字符,您都閱讀它們,並且在您的情況下,您只關心第一個字符 - 這使得事情很容易。

需要單字符輸入

由於這是您的要求之一,您可以簡單地通過檢查fgets()填充的字符數組是否包含'\n'作為數組中的第二個字符來處理此問題。 雖然此檢查對您使用有效字符沒有任何影響,但您可以提醒用戶他只需輸入單個字符,如下所示:

#include <stdio.h>

#define MAXC 1024       /* if you need a constant, #define one (or more) */

int getkeypress (char *line)
{
    while (1) { /* loop continually until valid input, manual EOF or empty-line */
        fputs ("\nEnter C, P or E: ", stdout);                  /* prompt for input */
        if (!fgets (line, MAXC, stdin)) {                       /* read entire line */
            puts ("(user canceled input, manual EOF)");         /* manual EOF case */
            return 0;
        }
        else if (*line == '\n')                                 /* empty line case */
            return 0;
        /* optional -- extra chars, does not effect validity C, P, or E as 1st char */
        else if (line[1] != '\n')
            fputs ("  error: trailing characters not allowed\n", stderr);
        else if (*line == 'C' || *line == 'P' || *line == 'E')  /* good input, done */
            break;
        else
            fputs ("  error: invalid input.\n", stderr);        /* all other errors */
    }
    
    return 1;
}

int main (void) {
    
    char buf[MAXC];
    
    while (getkeypress (buf))                       /* while good input */
        printf ("Good input: %c\n", *buf);
}

注意:字符數組bufmain()中聲明,然后將緩沖區作為參數傳遞給getkeypress() function,它將輸入存儲在緩沖區中,然后在成功時返回1 ,或者在手動EOF時返回0是由用戶按Ctrl + d (或 Windows 上的Ctrl + z )或用戶通過簡單地按Enter和空行結束輸入而生成的)

無論您使用哪種輸入 function,用戶輸入的方法都是相同的。 您不斷循環,直到用戶提供有效輸入,檢查使用的輸入 function 的返回並應用您必須確定輸入是否有效的任何標准。 當收到有效輸入時,您只需break; 輸入循環並返回成功。

示例使用/輸出

$ ./bin/getCPE

Enter C, P or E: Charlie Pappa Echo
  error: trailing characters not allowed

Enter C, P or E: c
  error: invalid input.

Enter C, P or E: P
Good input: P

Enter C, P or E: E
Good input: E

Enter C, P or E: C
Good input: C

Enter C, P or E: Catfish
  error: trailing characters not allowed

Enter C, P or E:

無論輸入多少,都使用一個字符

如上所述,如果您只關心輸入的第一個字符是'C''P'還是'E' ,則不必將用戶的輸入限制為單個字符。 您可以簡單地選擇忽略第一個字符之后的所有字符,同時使用輸入的任何有效'C''P''E'作為第一個字符。 通過使用面向行的輸入 function - 所有字符都被消耗(達到用於存儲的 memory 的數組或塊的限制)。 從這個意義上說,是否輸入了其他字符並不重要,只要第一個字符有效即可。

通過刪除與尾隨字符相關的錯誤,這實際上使 function 更簡單,例如

int getkeypress (char *line)
{
    while (1) { /* loop continually until valid input, manual EOF or empty-line */
        fputs ("\nEnter C, P or E: ", stdout);                  /* prompt for input */
        if (!fgets (line, MAXC, stdin)) {                       /* read entire line */
            puts ("(user canceled input, manual EOF)");         /* manual EOF case */
            return 0;
        }
        else if (*line == '\n')                                 /* empty line case */
            return 0;
        else if (*line == 'C' || *line == 'P' || *line == 'E')  /* good input, done */
            break;
        
        fputs ("  error: invalid input.\n", stderr);            /* handle error */
    }
    
    return 1;
}

示例使用/輸出

$ ./bin/getCPE2

Enter C, P or E: Charlie Pappa Echo
Good input: C

Enter C, P or E: c
  error: invalid input.

Enter C, P or E: P
Good input: P

Enter C, P or E: E
Good input: E

Enter C, P or E: C
Good input: C

Enter C, P or E: Catfish
Good input: C

Enter C, P or E:

上面注意,唯一的區別是以'C''P''E'開頭的輸入被視為有效 - 如果這是你真正關心的,那很好。

如果您還有其他問題,請仔細查看並告訴我。 如果您絕對必須使用scanf()它是可行的——但只有在您充分了解 function 之后才能知道為什么不應該開始使用它。 如果您必須使用它,請告訴我,我很樂意為您提供進一步幫助。

暫無
暫無

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

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