1

I have part of a function declared like this:

char keystroke;
printf("\n(a)dd, (d)elete, or (m)odify (use - and + to navigate left and right)");
keystroke = getchar();
switch (keystroke){...

for whatever reason, I cannot continue into the switch statement. The output looks like this:

(a)dd, (d)elete, or (m)odify (use - and + to navigate left and right)eginning at (5,6)
s
s
s
a
a
a
f

where the chars after are my attempted input. gdb says No symbol "keystroke" in current context so I guess it is not being recorded for some reason? Any idea why?

Edit:

Here is the function in question. It's a bit long and involved, and uses a few global variables.

struct inputlist{
 int coords[2];
 struct inputlist *next;
};
input *head;

typedef struct inputlist input;

void inpt()
{
  input *temp=head;
  input *temp2;
  char keystroke;
  int cursor = 0;
  int counter = 0;
  int i;
  int impx[2]= {0};
  int impy[2]= {0};
  int end = 0;

  if(temp)
    while(temp->next)
      temp = temp->next;

  while(1)
  {
    printf("Please enter the x coordinate or s to stop.");
    if(!scanf("%d",impx))
      break;
    if((!impx[0]<=0)&&(!impx[0]>=7))
    {
      printf("Please enter a number: [0,7]");
      continue;
    }
    printf("Please enter the y coordinate or s to stop.");
    if(!scanf("%d",impy))
      break;
    if((!impy[0]<=0)&&(!impy[0]>=7))
    {
      printf("Please enter a number: [0,7]");
      continue;
    }

    temp2 = malloc(sizeof(input));
    if(!temp2)
      exit(2);
    if(!head)
      head = temp2;
    temp2->next = NULL;
    if(temp)
      temp->next = temp2;
    else
      head = temp = temp2;
    temp2->coords[0] = impx[0];
    temp2->coords[1] = impy[0];
    }
    if(!head)
     exit(0);
    temp = head;


    while(!end)
    {
      int is_correct = 0;
      counter = 0;
//    printf("\033[");
      while(temp->next)
      {
        if(counter++==cursor)
          printf("*");
        else
          printf(" ");
        printf("(%d,%d)",temp->coords[0],temp->coords[1]);
        temp = temp->next;
      }

      printf("\n(a)dd, (d)elete, or (m)odify (use - and + to navigate left and right)");
      keystroke = getchar();
      switch (keystroke)
      {
        case 'a':
          while(temp)
          temp=temp->next;
          do
          {
            scanf(" %d",impx);
            scanf(" %d",impy);
            if ((impx[0]<=7)&&(impx[0]>=0)&&(impy[0]<=7)&&(impy>=0))
            {
              temp->next = malloc(sizeof(input));
              temp = temp->next;
              temp->next = NULL;
              temp->coords[0] = impx[0];
              temp->coords[1] = impy[0];
              is_correct = 1;
             }
           } while(!is_correct);
           break;
         case 'd':
           temp = head;
           for(i = 0; i<cursor-1;i++)
           temp = temp->next;
           temp2= temp->next;
           temp->next = temp2->next;
           free(temp2);
           break;
         case 'm':
         temp = head;
         for(i=0; i<cursor;i++)
           temp = temp->next;
         do
         {
           scanf(" %d",impx);
           scanf(" %d",impy);
           if ((impx[0]<=7)&&(impx[0]>=0)&&(impy[0]<=7)&&(impy>=0))
           {
             temp->coords[0] = impx[0];
             temp->coords[1] = impy[0];
             is_correct = 1;
           }
         } while(!is_correct);
         break;
         case '+':
         case '='://because who wants to hit shift? not me
         temp = head;
         for(i=0;i<cursor;i++)
           temp = temp->next;
         if(temp->next)
           cursor++;
         break;
         case '-':
         case '_':
         if(cursor)
           cursor--;
         break;
         default: 
           end = 1;
           break;
       }
     }
   }
jfa
  • 1,047
  • 3
  • 13
  • 39
  • Do you handle other characters that the user might input ? E.g. the '\n' that likely occurs when Enter is pressed ? – nos Feb 24 '14 at 08:42
  • I do, I use scanf earlier in the program. I just tried an fflush(stdin), no luck – jfa Feb 24 '14 at 08:44
  • Take a look to : [Cannot figure out how to use getchar(); in C][1] [1]: http://stackoverflow.com/a/19059797/3315914 – rpax Feb 24 '14 at 08:46
  • can you show the switch body ? – Santhosh Pai Feb 24 '14 at 08:47
  • 2
    Please include a [Short, Self Contained, Correct Example](http://www.sscce.org/) in your question. – Lee Duhem Feb 24 '14 at 08:47
  • 3
    BTW, the return value of `getchar()` is an `int`, not a `char`. – Lee Duhem Feb 24 '14 at 08:48
  • It looks like if you have corrupted your memory before this code. In particular the zero which shall terminate your string constant seems to go away. – Marian Feb 24 '14 at 08:50
  • @JFA Did you use like this switch(keystroke) { case 'a': statement ; continue or break}; – Chandru Feb 24 '14 at 08:51
  • @rpax I saw that one. I'm not sure why they're recommending I build a parser vs using the function getchar. – jfa Feb 24 '14 at 08:53
  • Plz format your question. – Abhineet Feb 24 '14 at 09:04
  • fflush(stdin) :: Undefined Behavior. – Abhineet Feb 24 '14 at 09:09
  • @Abhineet I just added that because someone earlier in the thread suggested it. It didn't work without it either. – jfa Feb 24 '14 at 09:13
  • @leeduhem I read that, someone that earlier. I don't understand why that would make a difference. Should I use a cast? If you use an int as a char, it returns the ascii value, which we know is a valid char. – jfa Feb 24 '14 at 09:16
  • When people say that it can cause an UB, you should at any cost avoid it. – Abhineet Feb 24 '14 at 09:19
  • @JFA That part of your code (1st block) is correct, Have a look at this once http://ideone.com/J2jgk7 ...?? – Daksh Shah Feb 24 '14 at 09:20
  • @DakshShah You mean use an if statement instead of a switch? That would make sense, but I don't see why it would fix my problem. – jfa Feb 24 '14 at 09:32
  • As a debugging tip can you try printing the value of `keystroke` after the `getchar()`. Also try placing `getchar()` after the line `keystroke = getchar();` to consume the newline char entered from first `getchar()`. – Sunil Bojanapally Feb 24 '14 at 09:43
  • @JFA Even this code is not giving me any problem (it has a switch) - http://pastebin.com/4W9mDrbY[I used codeblocks to compile], Both willl work (ideone link: http://ideone.com/J2jgk7) – Daksh Shah Feb 24 '14 at 09:44
  • suggestion: use `fgets` and `sscanf` instead of `scanf`, it is better to keep the input buffer free from "left-overs". – AndersK Feb 24 '14 at 09:52
  • @Claptrap I did change that, I'll change the question to reflect that. After further review, it looks like it's simply skipping that statement and was getting hung up in an infinite loop in another part of the problem, which I fixed – jfa Feb 24 '14 at 09:53

1 Answers1

2
  1. After jump out from the while(1) loop, there are some failed-match input in the input buffer, you need to consume them before you enter the while (!end) loop. You can do this by something like:

    while ((keystroke = getchar()) != '\n') ;
    

    If you did not consum them, the getchar() in the while(!end) will read from them.

  2. In the while(!end) loop, if you input a or m, you need to input two intergers, without any prompt, you should add some.

Lee Duhem
  • 14,695
  • 3
  • 29
  • 47
  • This solves the problem of the input, but now I'm receiving a segfault. Any idea where this is coming from? – jfa Feb 24 '14 at 10:02
  • 1
    @JFA Because after `while(temp) temp=temp->next;`, `temp` become a NULL pointer, but in the `case 'a'`, you still try to access its member by `temp->next = ...`. And there are other problems in your code, such as the use of `impy`. – Lee Duhem Feb 24 '14 at 10:07
  • Yes this is definitely the weak part of my project. But I don't see a problem in 'a'. Once temp becomes null, the while loop will terminate, then the next thing I do is set it to malloc. Although I suppose I should make the while loop temp->next and then set temp->next to malloc. Good catch. – jfa Feb 24 '14 at 12:05
  • Another thing is when I had both the while loop and scanf, it accepted an input then crashed, but when I took out scanf, it didn't accept an input again – jfa Feb 24 '14 at 12:07
  • @JFA If `temp` is NULL, `temp->next` itself will crash you program; and that is what happened in `case 'a'`. – Lee Duhem Feb 24 '14 at 12:32