为什么printf与%d说明符给出错误的结果?

时间:2017-05-24 11:50:40

标签: c printf scanf

这里的代码给出了int num的错误值,如果我输入的num是例如11,printf函数将输出0.但是如果我将静态加到int num,printf生成的输出是正确的。有人可以解释原因。如果我将第二个scanf的格式说明符设为%c,那么也可以正确打印int值。

img

4 个答案:

答案 0 :(得分:2)

char ch;
scanf("%d", &ch);

将调用未定义的行为,因为您使用的是整数格式,以将其存储在字符中。

答案 1 :(得分:2)

并非专门针对printf(),问题是由对scanf()的错误调用引起的。

引用C11,章节§7.21.6.2

  

[...]除非*表示分配抑制,否则   转换结果放在下面第一个参数指向的对象中   尚未收到转换结果的format参数。如果是这个对象   没有合适的类型,或者无法表示转换结果   在对象中,行为是未定义的。

对于%d转换说明符,预期的参数类型为

  

d [....]相应的参数应该是指针   有符号整数。

但是,你所提供的只是指向char的指针。不匹配。 Undefined behavior

OTOH,%c转换说明符,

  

c匹配字段指定的字符序列   width (如果指令中没有字段宽度,则为1)。   如果不存在l长度修饰符,则相应的参数应为a   指向大小足以接受的字符数组的初始元素的指针   序列。没有添加空字符。

所以使用

 scanf("%c",&ch);

是对的。或者,您也可以使用

 scanf("%hhd",&ch);    //char is signed
 scanf("%hhu",&ch);   //char is unsigned

答案 2 :(得分:1)

您观察到的很可能是因为第二个scanf错误(char工具大)格式说明符会覆盖num所在的自动变量内存。

使num静态将其移动到全局变量内存并且它(种类)有效,但它仍然是未定义的行为,某些内存已被覆盖,您可能需要付出代价稍后的。因此,唯一的选择是指定正确的格式说明符,如您所指出的那样%c

答案 3 :(得分:0)

尝试添加<?php /** * Magento * * NOTICE OF LICENSE * * This source file is subject to the Open Software License (OSL 3.0) * that is bundled with this package in the file LICENSE.txt. * It is also available through the world-wide-web at this URL: * http://opensource.org/licenses/osl-3.0.php * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to license@magentocommerce.com so we can send you a copy immediately. * * DISCLAIMER * * Do not edit or add to this file if you wish to upgrade Magento to newer * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * * @category Mage * @package Mage_Catalog * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ /** * Product options text type block * * @category Mage * @package Mage_Catalog * @author Magento Core Team <core@magentocommerce.com> */ class Mage_Catalog_Block_Product_View_Options_Type_Select extends Mage_Catalog_Block_Product_View_Options_Abstract { /** * Return html for control element * * @return string */ public function getValuesHtml() { $_option = $this->getOption(); $configValue = $this->getProduct()->getPreconfiguredValues()->getData('options/' . $_option->getId()); $store = $this->getProduct()->getStore(); if ($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_DROP_DOWN || $_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_MULTIPLE) { $require = ($_option->getIsRequire()) ? ' required-entry' : ''; $extraParams = ''; $select = $this->getLayout()->createBlock('core/html_select') ->setData(array( 'id' => 'select_'.$_option->getId(), 'class' => $require.' product-custom-option' )); if ($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_DROP_DOWN) { $select->setName('options['.$_option->getid().']'); // ->addOption('', $this->__('Please Select')); } else { $select->setName('options['.$_option->getid().'][]'); $select->setClass('multiselect'.$require.' product-custom-option'); } // This is a very specific case for Ring Size // $isMale = $isFemale = $hasNoPrice = false; // foreach ($_option->getValues() as $_value) { // if ($_value->getTitle() == 'I' && $_value->getPrice() == 0.0000) { // $isFemale = true; // } // else if ($_value->getTitle() == 'M' && $_value->getPrice() == 0.0000) { // $isMale = true; // } // if ($_value->getPrice() == 0.0000) { // $hasNoPrice = true; // } // } foreach ($_option->getValues() as $_value) { $priceStr = $this->_formatPrice(array( 'is_percent' => ($_value->getPriceType() == 'percent'), 'pricing_value' => $_value->getPrice(($_value->getPriceType() == 'percent')) ), false); $select->addOption( $_value->getOptionTypeId(), $_value->getTitle() . ' ' . $priceStr . '', array('price' => $this->helper('core')->currencyByStore($_value->getPrice(true), $store, false)) ); // Set Default for the following cases: // Ring Size for Men = T, Women = M // Price for Custom Option is $0 and is the last, unless defaulted by Men or Women. // if ($_value->getTitle() == 'M' && $isFemale) { // $select->setValue($_value->getOptionTypeId()); // } // else if ($_value->getTitle() == 'T' && $isMale) { // $select->setValue($_value->getOptionTypeId()); // } // else if ($_value->getPrice() == 0.0000 && $hasNoPrice && !$isFemale && !$isMale) { // $select->setValue($_value->getOptionTypeId()); // } //not sure about this line if ($sku_code[0] == 'F') { $select->setValue($configValue); } else if ($_value->getTitle() == 'M') { $select->setValue($_value->getOptionTypeId()); } else if ($_value->getTitle() == 'T') { $select->setValue($_value->getOptionTypeId()); } } if ($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_MULTIPLE) { $extraParams = ' multiple="multiple"'; } if (!$this->getSkipJsReloadPrice()) { $extraParams .= ' onchange="opConfig.reloadPrice()"'; } $select->setExtraParams($extraParams); if ($configValue) { $select->setValue($configValue); } return $select->getHtml(); } if ($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_RADIO || $_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_CHECKBOX ) { $selectHtml = '<ul id="options-'.$_option->getId().'-list" class="options-list">'; $require = ($_option->getIsRequire()) ? ' validate-one-required-by-name' : ''; $arraySign = ''; switch ($_option->getType()) { case Mage_Catalog_Model_Product_Option::OPTION_TYPE_RADIO: $type = 'radio'; $class = 'radio'; if (!$_option->getIsRequire()) { $selectHtml .= '<li><input type="radio" id="options_' . $_option->getId() . '" class="' . $class . ' product-custom-option" name="options[' . $_option->getId() . ']"' . ($this->getSkipJsReloadPrice() ? '' : ' onclick="opConfig.reloadPrice()"') . ' value="" checked="checked" /><span class="label"><label for="options_' . $_option->getId() . '">' . $this->__('None') . '</label></span></li>'; } break; case Mage_Catalog_Model_Product_Option::OPTION_TYPE_CHECKBOX: $type = 'checkbox'; $class = 'checkbox'; $arraySign = '[]'; break; } $count = 1; foreach ($_option->getValues() as $_value) { $count++; $priceStr = $this->_formatPrice(array( 'is_percent' => ($_value->getPriceType() == 'percent'), 'pricing_value' => $_value->getPrice($_value->getPriceType() == 'percent') )); $htmlValue = $_value->getOptionTypeId(); if ($arraySign) { $checked = (is_array($configValue) && in_array($htmlValue, $configValue)) ? 'checked' : ''; } else { $checked = $configValue == $htmlValue ? 'checked' : ''; } $selectHtml .= '<li>' . '<input type="' . $type . '" class="' . $class . ' ' . $require . ' product-custom-option"' . ($this->getSkipJsReloadPrice() ? '' : ' onclick="opConfig.reloadPrice()"') . ' name="options[' . $_option->getId() . ']' . $arraySign . '" id="options_' . $_option->getId() . '_' . $count . '" value="' . $htmlValue . '" ' . $checked . ' price="' . $this->helper('core')->currencyByStore($_value->getPrice(true), $store, false) . '" />' . '<span class="label"><label for="options_' . $_option->getId() . '_' . $count . '">' . $_value->getTitle() . ' ' . $priceStr . '</label></span>'; if ($_option->getIsRequire()) { $selectHtml .= '<script type="text/javascript">' . '$(\'options_' . $_option->getId() . '_' . $count . '\').advaiceContainer = \'options-' . $_option->getId() . '-container\';' . '$(\'options_' . $_option->getId() . '_' . $count . '\').callbackFunction = \'validateOptionsCallback\';' . '</script>'; } $selectHtml .= '</li>'; } $selectHtml .= '</ul>'; return $selectHtml; } } } ,例如\n。也许可以帮上忙。 如果您使用scanf("%d\n", &num);

这样的表达式,编译器将无法通过