3

リンクリストに文字を入力しようとしています。文字は「A」、「a」、「G」、「g」、「T」、「t」、「C」、「c」のいずれかになります。

私はまだ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をまっすぐ通過し、ループするたびに2つのループを実行します。誰かが私がどこで間違っているのか教えてもらえますか?

完全なプログラム:

#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 ;
}
4

4 に答える 4

13

改行を処理しません。指定子は%c空白をスキップしません。試す:

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

または、明示的なテストを追加することもできます。

scanf(...);
if (newChar == '\n')
    continue;
于 2012-12-04T19:59:24.943 に答える
6

"%c"改行文字をキャッチするためにスペースを追加します。スペース文字は、スペース文字、表、改行をキャッチするために使用されます

scanf("%c ",&newChar);
于 2012-12-04T20:00:35.483 に答える
4

あなたは'\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>

どのように処理するかに関係なく、ポイントは改行文字を消費する必要があるということです。

于 2012-12-04T20:00:09.227 に答える
0

使用する

newChar=getche();

これは、キーボードから文字を取得し、画面にエコーする非標準の関数です。

于 2017-10-20T18:29:30.543 に答える