我遇到问题,获得正确数量的参数:
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 )。
答案 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
告诉你传递了多少命令参数,但它无法告诉你将解析多少个选项。但这不应该是一个问题。