2012-12-04 60 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(); 

这是一个非标准的功能,从键盘得到一个字符,呼应屏幕。