ошибка printf «Попытка изменения значения, доступного только для чтения»

#perl #printf

#perl #printf

Вопрос:

при попытке распечатать объект, как в:

 print "$response{_content} n";
printf OUTPUT "$response{_content} n"; 
  

Инструкция printf генерирует ошибку «Попытка изменения значения, доступного только для чтения»

Это прерывистая ошибка. Случается только время от времени, но эта программа должна быть надежной на 100%. черт возьми.

В стандартном режиме выводится нормально.

Что я делаю не так? тьфу!

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

1. Почему вы меняете значение с print на printf при печати в дескриптор файла? (Кроме того, почему вы все еще используете глобальные FILEHANDLE переменные вместо переменных с лексической областью видимости?)

2. Что сказал Крис:D Из документов: » Первый аргумент списка будет интерпретироваться как формат printf [..] Не попадайтесь в ловушку использования printf, когда подойдет простая печать. Печать более эффективна и менее подвержена ошибкам »

3. прохладный. Спасибо. я думал, что мне нужно использовать printf для печати в дескриптор файла. Спасибо.

Ответ №1:

Первый аргумент printf интерпретируется как формат вывода, а не как сам вывод. Подробности см. в perldoc -f printf и man 3 printf.

Проблема в том, что printf иногда может пытаться выполнить запись в свои аргументы (это даже было источником нескольких уязвимостей в программах на C), например:

 perl -we 'printf "abc%nn", $_; print "$_n";'
  

Как вы можете видеть, это значение устанавливается $_ равным 3, что соответствует количеству символов, записанных до %n возникновения. Попробуйте %n без дополнительных аргументов, и вы увидите точное сообщение об ошибке из OP.

Короче говоря: используйте print , если вам действительно не нужно расширенное форматирование. Оставьте первый аргумент для printf r / o, если вам действительно не нужно еще более сложное форматирование.

Ответ №2:

Вам нужно будет проверить стандартный вывод на наличие сбоев. Я предполагаю, что время от времени $response{_content} содержит последовательности, которые имеют особое значение для printf.

Ответ №3:

У меня только что было такое же сообщение об ошибке, также с printf, но я делал это:

 printf "%-10s $valuen", $label;
  

Значение иногда содержало данные в шестнадцатеричном коде из блогов. Помимо выполнения заполнения с помощью оператора «x», я обнаружил, что получение значения из строки формата также работает:

 printf "%-10s %sn", $label, $value;
  

Я думал, что проблема в строке формата может быть связана с тем, что проценты (%) интерпретируются как форматированное значение, но из-за манипуляций с амперсандами (amp;) ошибка исчезла. В любом случае, вставка значения, в котором оно будет интерпретироваться, теперь кажется чем-то, чего следует избегать.