我目前正在通过K& R的
int main(int argc, char *argv[])
{
do something
}
根据我的理解,在某些时候,必须计算传递给程序的参数数量并将其存储在argc
中。此外,必须存储参数本身,并且指向每个参数的指针存储在数组argv
中,其中argv[0]
是指向命令名称的指针,argv[argc]
是空指针。这些步骤不可能神奇地发生,必须在某处定义此行为!
作为一个例子,假设我想存储传递给程序firstc
的每个参数的第一个字符,并丢弃该参数的其余部分(让我们假装我真的,这样做的理由很充分)。我可以像这样编写main():
int main(char firstc[])
{
do something
}
显然,使用默认argc
和argv
已经很容易做到这一点,我实际上并没有真正做到这一点。我甚至无法想象这实际上是必要的情景,但我很想知道它是否可能。
所以我的(完全理论上的,完全不切实际的)问题是:是否可以为命令行参数定义自己的行为?如果是的话,怎么会这样做呢?如果它是相关的,我使用的是Ubuntu 16.04和GNOME终端。
P.S。
我刚刚在写这个问题时意识到,完全有可能(可能是可能的)C脚本完全不知道外面发生了什么,并且终端仿真器正在准备命令行参数C程序。
答案 0 :(得分:5)
参数的设置实际上并不在C标准的范围内,它只是规定了您可以使用的main
的允许形式。这有两种规范形式(假设托管实现),一种是argc/argv
选项,另一种是void
选项(尽管注意实现可以免费提供其他实现)。
通常,有一些代码在调用 main
之前运行,例如来自crt0.o
等对象文件中的启动代码。
然而,如上所述,该标准并未规定在该阶段发生的任何事情,它是"环境"的责任。正确设置内容以便可以调用main
。
就你所要求的内容而言,我怀疑最简单的解决方案是提供main
采用规范形式,并简单地用每个参数的第一个字符调用myMain
,尽管你会可能需要智能地处理可能赋予main
的任意数量的参数。
以下示例可以处理一到三个参数:
#include <stdio.h>
int myMain0(void) {
printf ("myMain0\n");
return 0;
}
int myMain1(char p1) {
printf ("myMain1 [%c]\n", p1);
return 0;
}
int myMain2(char p1, char p2) {
printf ("myMain2 [%c] [%c]\n", p1, p2);
return 0;
}
int main(int argc, char *argv[]) {
switch (argc) {
case 1: return myMain0();
case 2: return myMain1(argv[1][0]);
case 3: return myMain2(argv[1][0], argv[2][0]);
}
printf ("Invalid argument count of %d\n", argc - 1);
return 1;
}
答案 1 :(得分:0)
操作系统是将参数数量和参数本身从命令行传递给C程序的操作系统。
函数main
对其参数并不挑剔。您根本不会参与任何争论,只能获得argc
,您可以同时获得argc
和argv
。
你甚至可以获得你想要的任何类型的3或4个参数,但它们将包含垃圾。操作系统将始终将参数的数量及其名称作为int和指向字符串的指针数组传递。
答案 2 :(得分:0)
您的code
声明实际上并未定义您获得的参数。这是程序环境的责任:操作系统和调用程序,通常是命令行处理器。
调用者(通常是一个shell程序)准备参数并将它们传递给适当的操作系统程序,以便调用程序。操作系统例程通常在堆栈上为被调用者准备这些数据,然后跳转到程序的入口点,然后进入<?php
global $wpdb;
$items_per_page = 10;
$id_post = isset( $_GET['id'] ) ? abs( (int) $_GET['id'] ) : 1;
$page = isset( $_GET['cpage'] ) ? abs( (int) $_GET['cpage'] ) : 1;
$chapter = isset( $_GET['chapter_no'] ) ? abs( (int) $_GET['chapter_no'] ) : 1;
$bookName= isset( $_GET['book'] ) ? urldecode ( $_GET['book'] ) : 1;
$offset = ( $page * $items_per_page ) - $items_per_page;
$query = "(Select id, hadith_no, content FROM data WHERE book='$bookName' AND chapter_no='$chapter')";
$total_query = "SELECT COUNT(*) FROM (${query}) AS combined_table";
$total = $wpdb->get_var( $total_query );
$latestposts = $wpdb->get_results("Select id, hadith_no, content FROM data WHERE book='$bookName' AND chapter_no='$chapter' LIMIT $items_per_page OFFSET $offset");
foreach ($latestposts as $latestpost) {
echo $latestpost->hadith_no." ".str_repeat(' ', 140)." <a href='http://localhost:8082/tps/permalinks/?id=$latestpost->id'>Permalink</a> ".$latestpost->content."<br>";
$text = $latestpost->content;
$words = extractCommonWords($text);
echo "Tags: <a>" .implode(' , ', array_keys($words)). "</a>";
echo do_shortcode('[Social9_Share]');
}
?>
函数。
您的main()
声明只是声明您的main
期望在堆栈上的内容,它间接定义了如何使用那些数据,但不是它们是什么。这就是为什么你可以在没有参数main()
的情况下宣布main
的原因 - 这只是意味着无论传递给我什么,我都会忽略它#。 / p>
答案 3 :(得分:0)
有标准(如ANSI C,C89等)提供主要规则和一组限制,并且有协议,不违反标准并为您提供一些可能性。
拳头,我还有一个例子:
#include <stdio.h>
int main(int argc, char * argv[], char * envs[])
{
int i = 1;
while (envs[i] != NULL)
{
printf("%d : %s\n", i, envs[i]);
i++;
}
return 0;
}
试着看看main
的第三个参数如何有用。
另外,我想解释一下命令行参数处理的方法。我制作ParseCommandLine
(或EvaluateParameters
)并在main
的开头调用它。该函数从命令行分析字符串并存储所有设置以便进一步方便使用。例如。如果我希望我的程序以
prog.exe -i input_file_name -o output_file_name -e
我会做类似的事情:
#include <string.h>
#include <stdio.h>
#define FNAME_LEN 20
struct settings
{
char inpFName[FNAME_LEN];
char outFName[FNAME_LEN];
bool isEncoded;
} globalSettings;
bool ParseCommandLine(int argc, char * argv[])
{
int c;
for (int c = 1; c < argc; c += 2)
{
if (!strcmp(argv[c], "-i") && c < argc - 1)
{
strncpy(globalSettings.inpFName, argv[c + 1], FNAME_LEN - 1);
continue;
}
if (!strcmp(argv[c], "-o") && c < argc - 1)
{
strncpy(globalSettings.outFName, argv[c + 1], FNAME_LEN - 1);
continue;
}
if (!strcmp(argv[c], "-e"))
{
globalSettings.isEncoded = true;
c--;
continue;
}
}
// rules to check mandatory values
if (strlen(globalSettings.inpFName) == 0 || strlen(globalSettings.outFName) == 0)
{
return false;
}
return true;
}
int main(int argc, char * argv[])
{
if (ParseCommandLine(argc, argv))
{
// do something
}
else
{
// explain how to run program
}
return 0;
}