如何计算C中的argc

时间:2017-11-02 10:43:58

标签: c arguments parameter-passing argv argc

我遇到问题,获得正确数量的参数:

    while((opt=getopt(argc, argv, ":a:c:SL")) != -1)

如果我启动脚本: ./script -a ok -c 1 -S -L  argc变量等于7

问题是我希望以./script -a ok -c 1 -SS -L argc变量等于7启动脚本,但它应该是8因(SS(或LL / CC)需要计为2 )。

3 个答案:

答案 0 :(得分:1)

你做不到。如果是这种情况,那么你需要自己解析论证并自己理解。大多数标准命令都以这种方式工作。

您无法更改argc的数量及其计数方式。要在没有getopt的情况下获得正确数量的计数,您只需自己计算argv

在我的小程序中,如果我需要这样的东西,我只需检查每个参数(没有getopt)。

使用getopt,您可以正确获取所有选项。您可以获得-SSS,然后您可以根据该选项决定行为。

不是编写自己的解析器选项计数或处理逻辑或类似的东西,而是有一种更好,更清晰的方法来实现同样的目的。( xtofl 的评论)。

  

简单的想法是使用多字符选项-S 3   这意味着-SSS。这样您就可以轻松解析它   并且还了解用户期望的行为类型   来自通过选项指定的程序。 1

一个小例子:

static const char help[] =
    "  -h       help help all this\n"
    "  -m times multiply by times\n"
    "  -s size  shift by size\n"
    "  -a add   addition by add\n"
    ;

int opt;
while ((opt = getopt(argc, argv, "hm:s:a:")) != -1)
{
    switch (opt)
    {
    case 'h':
        puts(help);
        return EXIT_SUCCESS;
    case 'm':
        opm = atoi(optarg);
        break;
    case 's':
        ops = atoi(optarg);
        break;
    case 'a':
        opa = atoi(optarg);
        break;
    default:
        return EXIT_FAILURE;
    }

1。这是一个意见问题,使用哪一个。两者在不同的实用程序中同样可用。解释事物的根本方式有所改变。除此之外,它们大致相同。

答案 1 :(得分:1)

这听起来像XY problem。我怀疑你想要计算@Service public class KafkaConsumer { @KafkaListener(topics = ("${kafka.input.stream.topic}"), containerFactory = "kafkaManualAckListenerContainerFactory", errorHandler = "listen3ErrorHandler") public void onMessage(ConsumerRecord<Integer, String> record, Acknowledgment acknowledgment ) throws Exception { try { msg = JaxbUtil.convertJsonStringToMsg(record.value()); onHandList = DCMUtil.convertMsgToOnHandDTO(msg); TeradataDAO.updateData(onHandList); acknowledgment.acknowledge(); recordSuccess = true; LOGGER.info("Message Saved in Teradata DB"); } catch (Exception e) { LOGGER.error("Error Processing On Hand Data ", e); recordSuccess = false; } } @Bean public ConsumerAwareListenerErrorHandler listen3ErrorHandler() throws InterruptedException { return (message, exception, consumer) -> { this.listen3Exception = exception; MessageHeaders headers = message.getHeaders(); consumer.seek(new org.apache.kafka.common.TopicPartition( headers.get(KafkaHeaders.RECEIVED_TOPIC, String.class), headers.get(KafkaHeaders.RECEIVED_PARTITION_ID, Integer.class)), headers.get(KafkaHeaders.OFFSET, Long.class)); return null; }; } } Container Class @Bean public Map<Object,Object> consumerConfigs() { Map<Object,Object> props = new HashMap<Object,Object> (); props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, localhost:9092); props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); props.put(ConsumerConfig.GROUP_ID_CONFIG, "example-1"); props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false); return props; } @SuppressWarnings({ "rawtypes", "unchecked" }) @Bean public ConsumerFactory consumerFactory() { return new DefaultKafkaConsumerFactory(consumerConfigs()); } @SuppressWarnings("unchecked") @Bean KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<Integer, String>> kafkaManualAckListenerContainerFactory() { ConcurrentKafkaListenerContainerFactory<Integer, String> factory = new ConcurrentKafkaListenerContainerFactory<>(); factory.setConsumerFactory(consumerFactory()); factory.getContainerProperties().setAckMode(AckMode.MANUAL); return factory; } 进程的参数数量的原因是访问任何不是选项的后续参数。

man page指向解决方案:

  

如果没有其他选项字符,getopt将返回-1。然后   getopt()是第一个optind元素的argv中的索引   选项。

完成argv循环后,您可以执行以下操作:

while

或者,您可以向上移动int i; for (i = optind; i < argc; i++) { printf("non-option arument: %s\n", argv[i]); } 以使其指向第一个非选项参数,并相应地递减argv。然后你可以从0开始索引:

argc

答案 2 :(得分:0)

getopt会将-SS解释为两个S选项。同样,它会将-SL解释为S选项,并附加L选项。它还会将-c2-c 2解释为带有参数c的{​​{1}}选项,即使第一个是单个命令行参数,第二个是两个参数

2告诉你传递了多少命令参数,但它无法告诉你将解析多少个选项。但这不应该是一个问题。