2015-12-10 4 views
1

Im довольно новичок в программировании на C. У меня проблема, с которой я все еще не мог избавиться после буквально часов исследований. Я собираюсь вставить мой (основной) исходный код ниже, если вам нужен пример. Проблема в основном заключается в следующем:Ошибка возврата измененного указателя

У меня есть метод, который возвращает 1 для успеха, 0 в противном случае. Он принимает int-pointer, который используется как фактическое возвращаемое значение функции, что означает, что переданный указатель модифицируется методом. Мне нужно работать с измененным значением позже. Поведение должно быть похоже на указатель буфера в функции, например fgets или scanf. Это отлично работает, пока я не попытаюсь вернуть измененное значение указателя из вызывающей функции. Я получаю ошибку нарушения доступа, а значение int - отрицательный максимум, соответственно. не определено. Как я буду делать это правильно?

Я читал о двойных указателях раньше, но не мог понять, как включить эту технику в мою программу ... Являются ли двойные указатели правильным подходом?

Ниже мой исходный код для справки :)

int validateInteger(int *out) { 
    char buffer[17]; 
    fgets(buffer, 16, stdin); 
    if (sscanf(buffer, "%d")) { 
     *out = atoi(buffer); 
     return 1; 
    } 
    return 0; 
} 

int anotherFunction() { 
    int selection = 0; 

    while(1) { 
     printf("Print something..."); 

     if (validateInteger(&selection) && selection >= 0 && selection <= 7) { 
      break; 
     } else { 
      clearScreen(); 
     } 
    } 
    return selection; 
} 

int main() { 

    while(1) { 
     int sel = anotherFunction(); // THIS IS WHAT DOESN'T WORK! 

     switch (sel) { 
     case 0: 
      return 0; 
     default: 
      printf("Print some error msg here..."); 
      return 1; 
     } 
    } 
} 

Любая помощь будет принята с благодарностью. Спасибо, ребята, заранее!

+0

'if (sscanf (buffer,"% d ")) {' what if this conditional is not true? –

+0

Если sscanf (buffer, "% d") неверен, функция возвращает 0 и не изменяет указатель int. – armin

ответ

3

Проблема заключается в следующих строках:

if (sscanf(buffer, "%d")) { 
    *out = atoi(buffer); 
    return 1; 
} 
  1. Вы не необходимо использовать как sscanf, так и atoi. Вам нужно использовать только один из них.
  2. Вы забыли пройти out до sscanf. Когда строка формата содержит %d, функция ищет указатель на int для чтения данных. Поскольку вы не передали этот аргумент, программа вызывает неопределенное поведение. В вашем случае это приводит к ошибке доступа.

Использование

if (sscanf(buffer, "%d", out) == 1) { 
    return 1; 
} 

Вы также можете использовать следующие вместо прежних линий.

*out = atoi(buffer); 
return 1; 

Однако, единственный способ проверить на наличие ошибок с помощью этого подхода заключается в том, чтобы проверить, является ли значение *out является 0. Если 0 является законным значением, то использование второго подхода не является хорошим. Поэтому я рекомендую первый подход.

+0

Звучит неплохо ... Я попробую это сразу: D – armin

1

Ваше использование sscanf() неверно! Вы никогда не передавали адрес переменной для сохранения отсканированного значения. Это вызывает undefined behaviour.

Согласно C11 стандартной, глава §7.21.6.2,

[..] Если нет достаточных аргументов для формата, поведение не определено.

Вы должны указать переменную для хранения отсканированных значение, что-то вроде R Sahu упоминается

if (sscanf(buffer, "%d", out) == 1) { 
    return 1; 
} 
+0

sscanf() не запрашивает ввод пользователя. Я использую его только для того, чтобы убедиться, что вход, который читается fgets(), можно преобразовать в целое. Это все еще неправильно? Как бы я сделал это правильно? – armin

+0

@armin Да, это неправильно. Вам нужно передать выходной параметр, а затем вместо использования 'atoi()', вы можете напрямую использовать значение этой переменной. :) –

Смежные вопросы