2012-12-04 83 views
2

我想輸入一個字符到鏈接列表中,其中的字符可以是'A','a','G','g','T',' t','C'或'c'。使用scanf輸入字符的問題()

我還不熟悉C,我知道我搞砸的東西在這裏:

do{ 
    printf ("\nEnter a new nucleotide: \n"); 
    scanf("%c",&newChar); 
      /* Checking */ 
    if(newChar == 'A' || 
    newChar == 'a' || 
    newChar == 'G' || 
    newChar == 'g' || 
    newChar == 'T' || 
    newChar == 't' || 
    newChar == 'C' || 
    newChar == 'c') 
    { 
    AddToSequence(newChar); 
    size++; 
    } else { 
    printf ("\nBad Element"); 
    } 
}while(newChar != 'x'); 

newChar與垃圾值初始化,在這種情況下,「Q」。

輸入'x'退出循環,輸入任何可接受的值調用AddToSequence(),並且任何不可接受的值都會收到警告。

由於某種原因,無論newChar中的值是多少,它都會跳轉到else。它也會直接跳過scanf而不用等待用戶輸入,每次循環時都會執行兩個循環。誰能告訴我我要去哪裏?

全部程序:

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

/*Structure declaration for the node*/ 
struct node{ 
    char nucleotide; 
    struct node *point; 
}*start; 

/* Adds a nucleotide to the chain. Creates a new linked list if no chain exists exists.*/ 
void AddToSequence(char nucleotide){ 
    struct node *loc, *first; 
    //Dynamic memory is been allocated for a node 
    first=(struct node*)malloc(sizeof(struct node)); 
    first->nucleotide=nucleotide; 
    first->point=NULL; 
    if(start==NULL){ 
    /*If list is empty*/ 
    start=first; 
    }else{ 
    /*Element inserted at the end*/ 
    loc=start; 
    while(loc->point!=NULL){ 
     loc=loc->point; 
     loc->point=first; 
    } 
    } 
} 

/* Display elements */ 
void Display(){ 
    struct node *loc; 
    if(start == NULL){ 
    printf ("\n\nList is empty"); 
    return; 
    } 
    loc=start; 
    printf("\n\nList is : "); 
    while(loc!=NULL){ 
    printf ("%c", loc->nucleotide); 
    loc=loc->point; 
    } 
    printf ("\n"); 
} 

/* Finds and displays percentage of the chain made up of each nucleotide. */ 
void Percentage(int size){ 
    struct node *loc; 
    if(start == NULL){ 
    printf ("\n\nList is empty"); 
    return; 
    } 
    loc=start; 
    printf("\n\nList is : "); 
    int A = 0, G =0, T =0, C = 0; 
    double Adouble = 0, Gdouble =0, Tdouble=0, Cdouble=0; 
    while(loc!=NULL){ 
    if(loc->nucleotide=='A' || 'a'){A++;} 
    if(loc->nucleotide=='G' || 'g'){G++;} 
    if(loc->nucleotide=='T' || 't'){T++;} 
    if(loc->nucleotide=='C' || 'c'){C++;}  
    loc=loc->point; 
    } 
    printf ("\n"); 

    /* Convert to double for percentages as int loses precision */ 
    Adouble =A; 
    Gdouble =G; 
    Tdouble =T; 
    Cdouble =C; 
    Adouble =(Adouble/size)*100; 
    Gdouble =(Gdouble/size)*100; 
    Tdouble =(Tdouble/size)*100; 
    Cdouble =(Cdouble/size)*100; 
    printf("\nA: %f", Adouble); 
    printf("\nG: %f", Gdouble); 
    printf("\nT: %f", Tdouble); 
    printf("\nC: %f", Cdouble); 
} 

/* There be dragons beyond here */ 
int main(){ 
    int navigate, size =0; 
    char newChar = 'q'; 
    do{ /* Menu */ 
    printf("\n 1. Create/Extend Sequence\n"); 
    printf("\n 2. Display Sequence\n"); 
    printf("\n 3. Count \n"); 
    printf("\n 0. Exit \n"); 
    printf("\nPlease select an option (0 to 3)\n"); 
    scanf("%d",&navigate); 
    switch (navigate){ 
     case 0: /* Exit */ 
     break; 
     case 1: /* Add nucleotides */ 
     do{ 
      printf ("\nEnter a new nucleotide: \n"); 
      scanf("%c",&newChar); 
      /* Some error checking */ 
      if(newChar == 'A' || newChar == 'a' || newChar == 'G' || newChar == 'g' || newChar == 'T' || newChar == 't' || newChar == 'C' || newChar == 'c'){ 
      AddToSequence(newChar); 
      size++; 
      } else { 
      printf ("\nBad Element"); 
      } 
     }while(newChar != 'x'); 
     break; 
     case 2: 
     Display(); 
     break; 
     case 3: 
     Percentage(size); 
     break; 
     default: 
     printf ("\n\nBad choice. Please select another.\n"); 
    } 
    } while (navigate !=0); 
    return 0 ; 
} 

回答

13

你不處理換行符。 %c說明符不會跳過空格。試試:

scanf(" %c", &newChar); 
    /*^<-- Makes `scanf` eat the newline. */ 

或者可能添加一個明確的測試。

scanf(...); 
if (newChar == '\n') 
    continue; 
+0

啊,謝謝!它總是那些小東西... – PatPat

+0

還有一點小障礙。 Scanf仍然看起來像是一個循環遲到的字符: 輸入'1'(菜單),'A'(用於輸入),'B'(失敗),'C'(用於輸入) A',在輸入'B'之後工作並且在輸入'C'之後再次失敗,其中'A'和'C'意圖通過。 – PatPat

+1

@PatPat不確定: - ?你使用'「%c」',對嗎? – cnicutar

3

你離開'\n'stdin

scanf("%d",&navigate); 
getchar(); // consume the newline character 
... 
scanf("%c",&newChar); 
getchar(); // consume the newline character 

或者因爲你已經在使用scanf()你可以告訴scanf函數本身照顧換行符:

scanf("%d\n", &navigate); 
.... 
scanf("%c\n",&newChar); 

更好的是,您可以通過在格式特定後添加空格來打開它:

scanf("%d ", &navigate); 
.... 
scanf("%c ",&newChar); 

萬一用戶想要做這樣的事情:2<tab key><enter key>

不管你如何處理它,關鍵是你需要消耗換行符。

5

增加空格到"%c"來捕捉換行符。空間字符內用於捕獲空格,製表符,換行符

scanf("%c ",&newChar); 
+0

另一個人把空間放在之前,你把它放在之後。有關係嗎? – PatPat

+0

正確的是之後,而不是之前,因爲你正在打字的charchter,然後新的線 – MOHAMED

+0

@PatPat我認爲你應該把它放在%c之前。它會在需要的時候使用換行符(例如,前一個'%d'將會破壞這個回答中的代碼)。另一方面,如果您使用「%c」,則無法構建方案來分解它。 – cnicutar

0

使用

newChar=getche(); 

這是一個非標準的功能,從鍵盤得到一個字符,呼應屏幕。