Linux 程序设计学习笔记----命令行参数处理

转载请注明出处.http://blog.csdn.net/suool/article/details/38089001

问题引入----命令行参数及解析

在使用linux时,与windows最大的不同应该就是经常使用命令行来解决大多数问题.比如下面这样的:

而显然我们知道C语言程序的入口是mian函数,即是从main函数开始执行,而main函数的原型是:

int main( int argc, char *argv[] );
int main( int argc, char **argv );

程序的 main 函数可以通过参数 argc 和 argv 来访问程序的参数列表(如果你不需要访问参数列表,你可以直接忽略它们)。第一个参数 argc 指示了命令行中参数的数量(这个值包含命令本身,如果后面没有参数,则值为1)。

第二个参数 argv 是一个字符串数组。其各个成员分别指向各个参数,即argv[0]指向命令本身,具体见下图.数组的大小由 argc 指定,而数组的元素则为各个命令行参数

的元素,表示以 NULL 结束的字符串形式。

使用命令行参数的过程因此被简化为检查 argc 和 argv 的内容。如果你对程序自己的名

字没有兴趣,记得跳过第一个参数.

下面的程序演示使用 argc 和 argv 的方法:

/*************************************************************************
	> File Name: arglist.c
	> Author: suool
	> Mail: [email protected]
	> Created Time: 2014年07月24日 星期四 16时35分40秒
 ************************************************************************/
#include <stdio.h>
int main (int argc, char* argv[])
{
    printf ("The name of this program is '%s'.\n", argv[0]);
    printf ("This program was invoked with %d arguments.\n", argc - 1);
    /* 指定了命令行参数么?*/
    if (argc > 1)
    {
        /* 有,那么输出这些参数。*/
        int i;
        printf ("The arguments are:\n");
        for (i = 1; i < argc; ++i)
        printf (" %s\n", argv[i]);
    }
    return 0;
}

结果如下:

几乎所有 GNU/Linux 程序都遵循一些处理命令行参数的习惯。程序期望得到的参数可以被分为两种: 选项( options ,又作 flags ) 和其它(非选项)参数。选项用于调整程序的

行为方式,而其它参数提供了程序的输入(例如,输入文件的名字)。

选项通常有两种格式:

· 短选项( short options ) 由一个短杠(hyphen)和一个字符(通常为一个大写或小写字母)组成。短选项可以方便用户的输入。

· 长选项( long options ) 由两个短杠开始,之后跟随一个由大小写字母和短杠组成的名字。长选项方便记忆和阅读(尤其在脚本中使用的时候)

通常程序会为它支持的选项提供长短两种形式,前者为便于用户理解,而后者为简化输入。例如,多数程序都能理解 –h 和 –help 这两个参数,并以相同方法进行处理。一般而

言,当从 shell 中调用一个程序的时候,程序名后紧跟的就是选项参数。如果一些选项需要一个参数,则参数紧跟在选项之后。例如,许多程序将选项 –output foo 解释为“将输出文

件设置为 foo”。

在选项之后可能出现其它命令行参数,通常用于指明输入文件或输入数据。例如,命令行 ls –s / 列举根目录的内容。选项 –s 改变了 ls 的默认行为方式,通知它为每个条目显示文件大小(以 KB 为单位)。参数 / 向 ls 指明了被列举的目录。选项 –size 与–s 选项具有相同的含义,因此调用 ls –size / 会得到完全相同的结果。

这时候我们就会发现一个问题,那就是如果参数比较多,而且要有一定的顺序怎么办?如何解析命令行的参数,判断参数的位置和正确与否呢?

这就是这次要讲的东西.

命令行参数识别

简单命令行处理getopt获取并解析命令行参数

getopt() 函数位于
unistd.h 系统头文件中,其原型如示:

int getopt( int argc, char *const argv[], const char *optstring );

给定了命令参数的数量 (argc)、指向这些参数的数组
(argv) 和选项字符串 (optstring)
后,getopt() 将返回第一个选项,并设置一些全局变量。使用相同的参数再次调用该函数时,它将返回下一个选项,并设置相应的全局变量。如果不再有识别到的选项,将返回 -1,此任务就完成了。

getopt() 所设置的全局变量包括:

  • optarg——指向当前选项参数(如果有)的指针。
  • optind——再次调用 getopt() 时的下一个
    argv 指针的索引。
  • optopt——最后一个已知选项。

对于每个选项,选项字符串 (optstring) 中都包含一个对应的字符。具有参数的选项后面跟有一个 : 字符。

其中optstrings 可以使下面的元素:

  • 1.单个字符,表示选项
  • 2.单个字符后面一个冒号:表示该选项后面必须跟一个参数.参数紧跟在选项后面或者以空格隔开,该参数的指针赋给optarg.
  • 3.单个字符后面跟两个冒号:: ,表示该选项后面可以跟一个参数.参数必须紧跟在选项后面不能以空格隔开.该参数一样赋给optarg.

如,如果opstrings = "ab:c::d::",命令行参数如下:

./getopt -a -b host -chello -d world.

这个命令行参数中,去掉短参数的-,其中a,b,c就是选项,host是b的参数,hello是c的参数,但是world不是d的参数,因为有空格隔开.

可以重复调用 getopt(),直到其返回 -1 为止;任何剩下的命令行参数通常视为文件名或程序相应的其他内容。

每执行一次,getopt函数将返回查找到的命令行输入的参数字符,并更新系统的全局变量,默认情况下,getopt函数会重新排列命令行参数的顺序,所有不可知的或者错误的命令行参数都排列到最后,getopt将返回-1,同时optind存储第一个未知的或者出错的选项的下标.

下面我们看两个示例程序.

1.有一个程序有三个选项a,b,c,其中b必须带参数,而c可以带可以不带.请写一个程序使用getopt来解析这个程序的命令行参数.

下面是代码示例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    int result;
    opterr = 0;             // 不输出错误信息
    while( (result = getopt(argc, argv, "ab:c::")) != -1 )
    {                         // 一直解析
           switch(result)
          {
               case 'a':
                   printf("option=a, optopt=%c, optarg=%s\n", optopt, optarg);
                   break;
              case 'b':
                   printf("option=b, optopt=%c, optarg=%s\n", optopt, optarg);
                   break;
              case 'c':
                   printf("option=c, optopt=%c, optarg=%s\n", optopt, optarg);
                   break;
              case '?':
                    printf("result=?, optopt=%c, optarg=%s\n", optopt, optarg);
                    break;
              default:
                   printf("default, result=%c\n",result);
                   break;
           }
        printf("argv[%d]=%s\n", optind, argv[optind]);
    }
    printf("result=-1, optind=%d\n", optind);    // 打印最后有可能出错的位置

    for(result = optind; result < argc; result++)   // 打印余下的错误选项
         printf("-----argv[%d]=%s\n", result, argv[result]);
    for(result = 1; result < argc; result++)        // 打印重新排列的选项列表
          printf("\nat the end-----argv[%d]=%s\n", result, argv[result]);
    return 0;
}

运行结果如下:

第一次命令行参数为:

./getopt_exp -a host -b hello -cworld -d

解析的结果为:

其他的请自己尝试吧,可以尝试一下没有错误的,或者更加错误的,

2.一个假想的 doc2html 程序的命令行处理。该 doc2html 程序将某种类型的文档转换为 HTML,具体由用户指定的命令行选项控制。它支持以下选项:

  • -I——不创建关键字索引。
  • -l lang——转换为使用语言代码 lang 指定的语言。
  • -o outfile.html——将经过转换的文档写入到
    outfile.html,而不是打印到标准输出。
  • -v——进行转换时提供详细信息;可以多次指定,以提高诊断级别。
  • 将使用其他文件名称来作为输入文档。

还将支持 -h 和 -?,以打印帮助消息来提示各个选项的用途。

先将代码贴如下:

/* getopt_demo - demonstrate getopt() usage
 *
 * This application shows you one way of using getopt() to
 * process your command-line options and store them in a
 * global structure for easy access.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

/* doc2html supports the following command-line arguments:
 *
 * -I - don't produce a keyword index
 * -l lang - produce output in the specified language, lang
 * -o outfile - write output to outfile instead of stdout
 * -v - be verbose; more -v means more diagnostics
 * additional file names are used as input files
 *
 * The optString global tells getopt() which options we
 * support, and which options have arguments.
 */
struct globalArgs_t {
	int noIndex;				/* -I option */
	char *langCode;				/* -l option */
	const char *outFileName;	/* -o option */
	FILE *outFile;
	int verbosity;				/* -v option */
	char **inputFiles;			/* input files */
	int numInputFiles;			/* # of input files */
} globalArgs;

static const char *optString = "Il:o:vh?";

/* Display program usage, and exit.
 */
void display_usage( void )
{
	puts( "doc2html - convert documents to HTML" );
	/* ... */
	exit( EXIT_FAILURE );
}

/* Convert the input files to HTML, governed by globalArgs.
 */
void convert_document( void )
{
	/* ... */
}

int main( int argc, char *argv[] )
{
	int opt = 0;

	/* Initialize globalArgs before we get to work. */
	globalArgs.noIndex = 0;		/* false */
	globalArgs.langCode = NULL;
	globalArgs.outFileName = NULL;
	globalArgs.outFile = NULL;
	globalArgs.verbosity = 0;
	globalArgs.inputFiles = NULL;
	globalArgs.numInputFiles = 0;

	/* Process the arguments with getopt(), then
	 * populate globalArgs.
	 */
	opt = getopt( argc, argv, optString );
	while( opt != -1 ) {
		switch( opt ) {
			case 'I':
				globalArgs.noIndex = 1;	/* true */
				break;

			case 'l':
				globalArgs.langCode = optarg;
				break;

			case 'o':
				/* This generates an "assignment from
				 * incompatible pointer type" warning that
				 * you can safely ignore.
				 */
				globalArgs.outFileName = optarg;
				break;

			case 'v':
				globalArgs.verbosity++;
				break;

			case 'h':	/* fall-through is intentional */
			case '?':
				display_usage();
				break;

			default:
				/* You won't actually get here. */
				break;
		}

		opt = getopt( argc, argv, optString );
	}

	globalArgs.inputFiles = argv + optind;
	globalArgs.numInputFiles = argc - optind;

	convert_document();

	return EXIT_SUCCESS;
}

下面分解上面的代码:

头文件:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

创建的 globalArgs 结构,用于以合理的方式存储命令行选项。由于这是个全局变量,程序中任何位置的代码都可以访问这些变量,以确定是否创建关键字索引、生成何种语言等等事项。最好让 main() 函数外的代码将此结构视为一个常量、只读存储区,因为程序的任何部分都可以依赖于其内容。每个命令行选择都有一个对应的选项,而其他变量用于存储输出文件名、指向输入文件列表的指针和输入文件数量。

struct globalArgs_t
{
    int noIndex;                /* -I option */
    char *langCode;             /* -l option */
    const char *outFileName;    /* -o option */
    FILE *outFile;
    int verbosity;              /* -v option */
    char **inputFiles;          /* input files */
    int numInputFiles;          /* # of input files */
} globalArgs;

static const char *optString = "Il:o:vh?";

选项字符串 optString 告知 getopt() 可以处理哪个选项以及哪个选项需要参数。如果在处期间遇到了其他选项,getopt() 将显示一个错误消息,程序将在显示了使用方法消息后退出。

下面的代码段包含一些从 main() 引用的用法消息函数和文档转换函数的小存根。可以对这些存根进行自由更改,以用于更为有用的目的。

void display_usage( void )
{
    puts( "doc2html - convert documents to HTML" );
    /* ... */
    exit( EXIT_FAILURE );
}

void convert_document( void )
{
    /* ... */
}

最后,下面的代码段中所示,在 main() 函数中使用此结构。和优秀的开发人员一样,需要首先初始化 globalArgs 结构,然后才开始处理命令行参数。在程序中,可以借此设置在一定情况下合理的缺省值,以便在以后有更合适的缺省值时更方便地对其进行调整

int main( int argc, char *argv[] )
{
    int opt = 0;

    /* Initialize globalArgs before we get to work. */
    globalArgs.noIndex = 0;     /* false */
    globalArgs.langCode = NULL;
    globalArgs.outFileName = NULL;
    globalArgs.outFile = NULL;
    globalArgs.verbosity = 0;
    globalArgs.inputFiles = NULL;
    globalArgs.numInputFiles = 0;

下面的代码段中的 while 循环和 switch 语句是用于本程序的命令行处理的代码部分。只要 getopt() 发现选项,switch 语句将确定找到的是哪个选项,将能在 globalArgs 结构中看到具体情况。当 getopt() 最终返回 -1 时,就完成了选项处理过程,剩下的都是输入文件了。

opt = getopt( argc, argv, optString );
    while( opt != -1 ) {
        switch( opt ) {
            case 'I':
                globalArgs.noIndex = 1; /* true */
                break;

            case 'l':
                globalArgs.langCode = optarg;
                break;

            case 'o':
                globalArgs.outFileName = optarg;
                break;

            case 'v':
                globalArgs.verbosity++;
                break;

            case 'h':   /* fall-through is intentional */
            case '?':
                display_usage();
                break;

            default:
                /* You won't actually get here. */
                break;
        }

        opt = getopt( argc, argv, optString );
    }

    globalArgs.inputFiles = argv + optind;
    globalArgs.numInputFiles = argc - optind;

既然已经完成了参数和选项的收集工作,接下来就可以执行程序所设计的任何功能(在本例中是进行文档转换),然后退出

convert_document();
    return EXIT_SUCCESS;
}

当然上面的使用optget是简单的命令行处理,如果你要进行长参数的或者稍微复杂的处理,那就继续往下看吧.getopt_long() 是同时支持长选项和短选项的getopt() 版本。

复杂的命令行处理getopt获取并解析命令行参数

getlongopt的原型是:

int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *indexptr)

第一个参数是当前传递进来的参数个数,第二个参数是当前传递进来的参数列表,第三个参数是当前进程所有可支持的短参数的字符串,第四个参数是struct option,表示所有的长参数的对应关系.

结构体声明如下:

struct option
{
   # if (defined __STDC__ && __STDC__) || defined __cplusplus
    const char *name;
   # else
    char * name;
   # endif
    int has_arg;   // 该参数是否需要带参数
    int *flag;     // 标志
    int val;       // 返回参数值
};

name 成员是指向长选项名称(带两个短横线)的指针。has_arg 成员设置为 no_argument、optional_argument, 或 required_argument(均在 getopt.h 中定义)之一,以指示选项是否具有参数。如果 flag 成员未设置为 NULL,在处理期间遇到此选项时,会使用
val 成员的值填充它所指向的 int 值。如果 flag 成员为 NULL,在 getopt_long() 遇到此选项时,将返回 val 中的值;通过将 val 设置为选项的 short 参数,可以在不添加任何其他代码的情况下使用 getopt_long()——处理 while loop 和 switch 的现有 getopt() 将自动处理此选项。

这已经变得更为灵活了,因为各个选项现在可以具有可选参数了。更重要的是,仅需要进行很少的工作,就可以方便地放入现有代码中。

此函数的返回情况如下:

1.在使用此函数处理一个参数时,全局变量optarg指向下一个要处理的变量,并返回struct option的第四个成员.一般情况下,如果struct option的第三个参数位置设置null,第四个参数一般设置为该长选项对应的短选项的字符值,即返回相应的短选项字符.

2.如果解析完最后一个成员将返回1

3.如果getlongopt遇到一个错误的选项,他将打印一个错误消息并返回‘?‘

4.当get_long解析一个长选项并且发现后面没有参数则返回‘:‘,表示缺少参数.

应用举例.

1.一个程序的所需的短选项和长选项如下:

短选项             长选项                         作用
-h                      --help                          输出程序的命令行参数说明并退出
-o filename     --output filename     给定输出文件名
-v                    --version                      显示程序当前的版本后退出 

在这个程序中,首先需要确定两个结构:

1,一个字符串,包含所需要的短选项字符,如果选项后面有参数,字符后面加一个冒号:.本例中,这个字符串应该是:"ho:v",因为-o后面有参数filename,所以要加冒号.

2,一个包含长选项的结构体数组.每个结构体四个域.

第一个域为长选项字符串.第二个域为表示相应的选项是否需要参数,只能为0,没有参数,1,必须要,2,可以要.第三个域决定返回结果类型(即是flags,建议设null),如果为null,则此函数将返回后一个域(即val,一般设置为当前获取的短参数值),否则,此函数将返回0.第四个域为函数的返回值,一般设置为对用的短选项的ascii值.

另外,结构体数组的最后一个元素全部设置为null和0,表示结束.

结构体可以如下所示:

    // 描述了长选项的 struct option 数组
    const struct option long_options[] =
    {
        { "help", 0, NULL, 'h' },
        { "output", 1, NULL, 'o' },
        { "version", 0, NULL, 'v' },
        { NULL, 0, NULL, 0 }                   // 数组末要求这样一个元素。
    };

以下是程序的代码:

#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

const char* program_name;			//the filename

void print_usage (FILE* stream, int exit_code)	//output message
{
    fprintf (stream, "Usage: %s options [ inputfile ... ]\n", program_name);
    fprintf (
        stream, " -h --help .\n"
        " -o --output filename.\n"
        " -v --version.\n"
            );
    exit (exit_code);
}

// main
int main (int argc, char* argv[])
{
    int next_option;	

    const char* const short_options = "ho:v";    // list of short options
    const struct option long_options[] =         // structure of long options
    {
        { "help", 0, NULL, 'h' },		//no arg
        { "output",1, NULL, 'o' },		//must have a arg
        { "version",0, NULL, 'v' },
        { NULL, 0, NULL, 0}             // necessary ele
    };

    const char* output_filename = NULL;
    program_name = argv[0];

    do
    {
        next_option = getopt_long (argc, argv, short_options, long_options, NULL);
        switch (next_option)
        {
            case 'h':     		//-h or --help, print the info of help
            print_usage (stdout, 0);
            break;
            case 'o':     		// -o or --output    print the content of the file
            output_filename = optarg;
            execl("/bin/cat","cat",output_filename,NULL);
            break;

            case 'v':   		//-v or    --version
            printf("the version is v1.0\n");
            break;
            case ':':
            break;
            case '?':
            print_usage (stderr, 1); // unknow
            break;
            default:                 // else
            print_usage (stderr, 1);
            break;
        }
    }while (next_option !=-1);
    return 0;
}

下面是测试结果:

1.命令行:

./getopt_long_exp -help

./getopt_long_exp -v

./getopt_long_exp --version

./getopt_long_exp --output getopt_long_exp.c

2.对上面的转换程序的修改:

getopt_long() 函数在 getopt.h 头文件(而非 unistd.h)中,因此将需要将该头文件包含进来。我还包含了 string.h,因为将稍后使用 strcmp() 来帮助确定处理的是哪个长参数。

其他头文件

#include <getopt.h>
#include <string.h>

已经为 --randomize 选项在 globalArgs 中添加了一个标志,并创建了 longOpts 数组来存储关于此程序支持的长选项的信息。除了 --randomize 外,所有的参数都与现有短选项对应(例如,--no-index 等同于 -I)。通过在选项结构中包含其短选项等效项,可以在不向程序添加任何其他代码的情况下处理等效的长选项。

扩展后的参数

opt = getopt_long( argc, argv, optString, longOpts, &longIndex );
    while( opt != -1 ) {
        switch( opt ) {
            case 'I':
                globalArgs.noIndex = 1; /* true */
                break;

            case 'l':
                globalArgs.langCode = optarg;
                break;

            case 'o':
                globalArgs.outFileName = optarg;
                break;

            case 'v':
                globalArgs.verbosity++;
                break;

            case 'h':   /* fall-through is intentional */
            case '?':
                display_usage();
                break;

            case 0:     /* long option without a short arg */
                if( strcmp( "randomize", longOpts[longIndex].name ) == 0 ) {
                    globalArgs.randomized = 1;
                }
                break;

            default:
                /* You won't actually get here. */
                break;
        }

        opt = getopt_long( argc, argv, optString, longOpts, amp;longIndex );
    }
将 getopt() 调用更改为了 getopt_long(),除了 getopt() 的参数外,它还接受 longOpts 数组和 int 指针
(longIndex)。当getopt_long() 返回 0 时,longIndex 所指向的整数将设置为当前找到的长选项的索引。

新的经改进的选项处理

opt = getopt_long( argc, argv, optString, longOpts, &longIndex );
    while( opt != -1 ) {
        switch( opt ) {
            case 'I':
                globalArgs.noIndex = 1; /* true */
                break;

            case 'l':
                globalArgs.langCode = optarg;
                break;

            case 'o':
                globalArgs.outFileName = optarg;
                break;

            case 'v':
                globalArgs.verbosity++;
                break;

            case 'h':   /* fall-through is intentional */
            case '?':
                display_usage();
                break;

            case 0:     /* long option without a short arg */
                if( strcmp( "randomize", longOpts[longIndex].name ) == 0 ) {
                    globalArgs.randomized = 1;
                }
                break;

            default:
                /* You won't actually get here. */
                break;
        }

        opt = getopt_long( argc, argv, optString, longOpts, amp;longIndex );
    }

我还添加了 0 的
case,以便处理任何不与现有短选项匹配的长选项。在此例中,只有一个长选项,但代码仍然使用 strcmp() 来确保它是预期的那个选项。

这样就全部搞定了;程序现在支持更为详细(对临时用户更加友好)的长选项。

Summarize

UNIX 用户始终依赖于命令行参数来修改程序的行为,特别是那些设计作为小工具集合 (UNIX 外壳环境)的一部分使用的实用工具更是如此。程序需要能够快速处理各个选项和参数,且要求不会浪费开发人员的太多时间。毕竟,几乎没有程序设计为仅处理命令行参数,开发人员更应该将精力放在程序所实际进行的工作上。

getopt() 函数是一个标准库调用,可允许使用直接的
while/switch 语句方便地逐个处理命令行参数和检测选项(带或不带附加的参数)。与其类似的 getopt_long() 允许在几乎不进行额外工作的情况下处理更具描述性的长选项,这非常受开发人员的欢迎。

既然已经知道了如何方便地处理命令行选项,现在就可以集中精力改进程序的命令行,可以添加长选项支持,或添加之前由于不想向程序添加额外的命令行选项处理而搁置的任何其他选项。

不要忘记在某处记录所有的选项和参数,并提供某种类型的内置帮助函数来为健忘的用户提供帮助。

reference:

linux高级程序设计 杨宗德

http://www.ibm.com/developerworks/cn/aix/library/au-unix-getopt.html

转载请注明出处.http://blog.csdn.net/suool/article/details/38089001

The Next:

1. ANSI C文件I/O管理

2. POSIX文件以及目录管理

3. Linux下的一些编码特性和规范

4. Python 两大网络框架

5. network programming.

Linux 程序设计学习笔记----命令行参数处理,布布扣,bubuko.com

时间: 2024-10-26 05:11:06

Linux 程序设计学习笔记----命令行参数处理的相关文章

Linux程序设计学习笔记----网络通信编程API及其示例应用

转载请注明出处, http://blog.csdn.net/suool/article/details/38702855. BSD Socket 网络通信编程 BSD TCP 通信编程流程 图为面向连接的Socket通信的双方执行函数流程.使用TCP协议的通信双方实现数据通信的基本流程如下 建立连接的步骤 1.首先服务器端需要以下工作: (1)调用socket()函数,建立Socket对象,指定通信协议. (2)调用bind()函数,将创建的Socket对象与当前主机的某一个IP地址和TCP端口

Linux程序设计学习笔记----System V进程间通信(信号量)

关于System V Unix System V,是Unix操作系统众多版本中的一支.它最初由AT&T开发,在1983年第一次发布,因此也被称为AT&T System V.一共发行了4个System V的主要版本:版本1.2.3和4.System V Release 4,或者称为SVR4,是最成功的版本,成为一些UNIX共同特性的源头,例如"SysV 初始化脚本"(/etc/init.d),用来控制系统启动和关闭,System V Interface Definitio

Linux程序设计学习笔记----进程间通信——管道

转载请注明出处: http://blog.csdn.net/suool/article/details/38444149, 谢谢! 进程通信概述 在Linux系统中,进程是一个独立的资源管理单元,但是独立而不孤立,他们需要之间的通信,因此便需要一个进程间数据传递.异步.同步的机制,这个机制显然需要由OS来完成管理和维护.如下: 1.同一主机进程间数据交互机制:无名管道(PIPE),有名管道(FIFO),消息队列(Message Queue)和共享内存(Share Memory).无名管道多用于亲

Linux 程序设计学习笔记----ANSI C 文件I/O管理

转载请注明出处:http://blog.csdn.net/suool/article/details/38129201 问题引入 文件的种类 根据数据存储的方式不同,可以将文件分为文本文件和二进制文件.具体的区别和关系如下: 文本文件与二进制文件在计算机文件系统中的物理存储都是二进制的,也就是在物理存储方面没有区别都是01码,这个没有异议,他们的区别主要在逻辑存储上,也就是编码上. 文本文件格式存储时是将值作为字符然后存入其字符编码的二进制,文本文件用'字符'作为单位来表示和存储数据,比如对于1

Linux 程序设计学习笔记----文件管理系统

本文部分整理自网络 Linux下文件系统管理 1.VFS文件系统概述 linux采用VFS来管理文件系统,而且linux设计的原则之一就是everything is file.因此文件管理系统是linux设计最核心的体现. VFS的全称是Virtual File System (虚拟文件系统). 总体上说 Linux 下的文件系统主要可分为三大块:一是上层的文件系统的系统调用,二是虚拟文件系统 VFS(Virtual Filesystem Switch),三是挂载到 VFS 中的各实际文件系统,

Linux 程序设计学习笔记----终端及串口编程基础之概念详解

转载请注明出处,谢谢! linux下的终端及串口的相关概念有: tty,控制台,虚拟终端,串口,console(控制台终端)详解 部分内容整理于网络. 终端/控制台 终端和控制台都不是个人电脑的概念,而是多人共用的小型中型大型计算机上的概念. 1.终端 一台主机,连很多终端,终端为主机提供了人机接口,每个人都通过终端使用主机的资源. 终端有字符哑终端和图形终端两种. 控制台是另一种人机接口, 不通过终端与主机相连, 而是通过显示卡-显示器和键盘接口分别与主机相连, 这是人控制主机的第一人机接口.

Linux 程序设计学习笔记----POSIX 文件及目录管理

转载请注明:http://blog.csdn.net/suool/article/details/38141047 问题引入 文件流和文件描述符的区别 上节讲到ANSI C 库函数的实现在用户态,流的相应资源也在用户空间,但无论如何实现最终都需要通过内核实现对文件的读写控制.因此fopen函数必然调用了对OS的系统调用.这一调用在LINUX下即为open, close, read, write等函数.这些都遵循POSIX标准. so,在linux系统中是如何通过POSIX标准实现对文件的操作和目

Linux 程序设计学习笔记----动手编写makefile文件

Befroe Beginning. 之前定了暑假的plan ,关于Linux的书籍现在在看的是ALP和Linux高级程序设计(杨宗德)第三版.在计划中的是Linux高级环境编程. 现在开始关于Linux程序设计的第一篇学习笔记. 本来打算把名字写成教程,不过觉得自己完全是新手在自学,还是写学习笔记比较负责和适合. 希望可以一起学习进步. 引入 首先我们假设这样一个场景.我们有一个程序包含了三个文件,分别是源码文件main_plus,c和function_plus.c以及头文件mydefine_p

Linux 程序设计学习笔记----文件管理实例应用

一.使用ls -l 以排序方式输出目录信息 1.需求以及知识点覆盖 ls -l 命令根据后面的参数将列出某文件即目录下的基本信息. 如果没有具体的目录或者文件,则列出当前目录下所有的非隐藏文件的信息,包括文件类型,文件权限,硬链接个数,拥有者.拥有者所在组,文件大小,文件更新时间等. such as : 若没有指定的文件,则输出所有目录下的文件信息: 所以,本应用要实现的基本功能和需要的知识点有: ①参数检查.包括参数个数检查,如果有多个需要列出信息的文件及目录,则遍历所有的参数,另外需要读取当