Не удается напечатать символ char после использования его в функции

#c #string #function #pointers #switch-statement

#c #строка #функция #указатели #switch-инструкция

Вопрос:

У меня есть входные данные, которые являются Number1, Number2Command, например 1,3c 1,5d 10,40p, я хочу передать «command» функции и получить ее обратно со значением c, d, p… В моем коде что-то не так с strpbrk (который возвращает указатель), потому что я не могу напечатать команду.

 #include <stdio.h>
#include <stdlib.h>
typedef enum Command
{
    ChangeCommand = 'c',
    DeleteCommand = 'd',
    PrintCommand = 'p',
    UndoCommand = 'u',
    RedoCommand = 'r',
} Command;
char input[1025];
void funzione(int *val1, int *val2, char command){
    fgets(input, 1025, stdin);
    if (input[0] == 'q')
    {
        exit(2);
    }
    char *pEnd;
    *val1 = strtol(input, amp;pEnd, 10);
    *val2 = strtol(pEnd   1, amp;pEnd, 10);
    char letters[5] = "crpud";
    command = strpbrk(input, letters);
}
int main(int argc, char *argv[]) {
    int val1;
    int val2;
    char command;
    funzione(amp;val1, amp;val2, command);
    printf("%d %d %c", val1, val2, command);
    switch (command)
        {
        case ChangeCommand:
   
            break;

        case DeleteCommand:
            
            break;

        case PrintCommand:
       
            break;

        case UndoCommand:
     
            break;

        case RedoCommand:
      
            break;
        default:
            exit(1);
            break;
        }
    return 0;
}
  

Комментарии:

1. Пожалуйста, отправьте минимально воспроизводимый пример .

2. Обратите внимание на предупреждения вашего компилятора. Многие из них должны быть решены и могут устранить вашу ошибку.

3. @ChristopherMoore ошибок нет, вот в чем проблема.

4. Я вижу несколько предупреждений .

5. Помните, что есть разница между ошибками и предупреждениями .

Ответ №1:

  • strpbrk() возвращает указатель, поэтому разыменуйте его, чтобы получить значение.
  • Аргументом command должен быть указатель типа val1 и val2 , чтобы он передавал информацию main() .
  • В letters нет завершающего нулевого символа, поэтому использовать его там, где ожидается строка, опасно.

Исправлен код:

 void funzione(int *val1, int *val2, char *command){ /* add * before command */
    /* omitted, same as original */
    char letters[] = "crpud"; /* remove explicit size to have it calculate including terminating null-character */
    char* p_command = strpbrk(input, letters); /* obtain a pointer */
    *command = p_command != NULL ? *p_command : ''; /* dereference it (avoid dereferencing NULL) */
}
  

И

 funzione(amp;val1, amp;val2, command);
  

в main() должно быть

 funzione(amp;val1, amp;val2, amp;command);
  

с amp; добавленным ранее command .

Ответ №2:

Как сказано в комментариях, компилятор выдает вам предупреждения не просто так. То, что вы делаете с command = strpbrk(input, letters) , — это преобразование char* (что strpbrk() возвращает) в char (что command есть).

Это в стороне, выполнение

 char letters[5] = "crpud";
command = strpbrk(input, letters);
  

находит первое вхождение «crpud» внутри input . Я думаю, что то, что вы хотите, это первое вхождение ‘c’, или ‘r’, или ‘p’, или ‘u’, или ‘d’ в input .
Вот один из способов решить эту проблему:

 
void funzione(int *val1, int *val2, char *command){
    fgets(input, 1025, stdin);
    if (input[0] == 'q')
    {
        exit(2);
    }
    char *pEnd;
    *val1 = strtol(input, amp;pEnd, 10);
    *val2 = strtol(pEnd   1, amp;pEnd, 10);
    char letters[5] = "crpud";
    for (int i=0; i<5; i  ) 
    {
        if (strchr(input, letters[i])) 
        {
            *command = letters[i];
            break;
        }
    }
}
  

Затем используйте funzione() с указателем на command :

 int val1;
int val2;
char command;
funzione(amp;val1, amp;val2, amp;command);