C语言命令行参数、文件操作及调试代码那些子事儿

命令行参数

在之前的学习中,main函数—般都是没有参数的,对应的,在运行时,—般就是直接输入可执行的程序文件名(例如. / main )
但是,实际上main函数是可以有参数的。可以将任何过去无参数的main函数替换成下面这种有参数的main函数

int main(int argc,char **argv)
{
    //......
}

在这里,main函数有两个参数
第一个参数是整数型,会传入命令行参数的个数,程序运行时就可以接收到。
第二个参数是char **,其中储存了用户从命令行传递进来的参数。

如果程序可执行文件名为main,则在命令行中输入./main hello world,就会得到argc为 3 , argv[0]为./main ,argv[1]为hello ,argv[2]为world。如果有更多参数也可以以此类推。

命令行参数默认都是空格分隔,但是如果希望包含空格的一个字符串作为参数,则需要在输入参数时用引号将其包裹起来。

如果程序可执行文件名为main,则在命令行中输入 . / main “hello world” is my greet,会得到argc为 5 , argv[0]为./main ,argv[1]为hello world , argv[2]为is ,argv[3]为my , argv[4]为greet .

任何被接收到的argv参数都可以被当做正常的字符串在代码里使用。在很多程序的设计中,需要根据接收到的参数来决定程序的执行方式,这时候,学会使用argc和argv就显得很重要了。

1、(对)在main函数中用于接收命令行参数的函数参数中,第一个是命令行参数的个数。
2、(错)命令行中键入./sort --min时,我们得到的argv[]是–min。
并不应该是–min,而应该是. / sort
3、(错)在int main(int argc,char **argv)中argc取到的是main函数的参数个数。
如果是main函数的参数的话,就固定为2了,肯定不对。它取到的应该是命令行中键入的参数个数。
4、(错)命令行读入的参数是从命令行键入的可执行程序路径(程序名)后一个空格开始计算。
并不是,可执行程序路径会被视为首个参数。

文件操作

在读文件的时候需要先有一个可以访问到文件的文件指针(file pointer),它是一个FILE类型的指针。

可以通过下面的方式声明一个文件指针。

FILE *fp;

这时候,如果对一个文件进行操作,需要先使用

fp = fopen(文件路径,访问模式);

将文件指针和文件关联起来,其中第一个参数是一个字符串,对应了希望访问的文件路径。第二个参数是访问模式,它可以是表示只读模式的"r”,也可以是表示只写模式的"w",还可以是在文件未尾追加的"a”。

将文件指针和文件关联起来后,就可以通过【fgetc(fp);】获得当前指针之后位置的一个字符了,每获得一个字符,指针会向后移动一个字符(如果到达文件尾部则会返回EOF )。
这时通过【fputc( 'c ', fp);】的方式将字符·c·写入到fp关联的文件内了。

了解到这些信息后,就可以实现将一个文件复制到另一个文件内的函数了,例如:

void filecopy(FILE *in_fp, FILE *out_fp)
{
    char ch;
    while ((ch = fgetc(in_fp)) != EOF)
    {
        fputc(ch,out_fp);
    }
}

这个函数接收的两个参数都是文件指针。这个函数会通过一个可读模式的文件指针逐字符地读取,并且通过一个可写模式的文件指针逐字符地将所有字符写出,从而起到复制文件内容的作用。

需要注意,在给文件指针进行命名的时候,要避开stdin、stdout和stderr这三个名称。因为这三个名称其实已经用于标准输入、标准输出、标准错误的文件指针。
看到的stdin、stdout和stderr 这三个文件指针可以直接使用
通过【fgetc(stdin);】获得来自标准输入的字符,也可以通过【fputc(ch,stdout);】或【fputc(ch,stderr);】将变量ch 中的字符输出到标准输出或标准错误中的。

除了fgetc和fputc之外,还可以使用fscanf和fprintf函数。这两个函数都很像已经很熟悉的scanf和printf函数,只是不过,scanf和printf可以被看作 fscanf和fprintf 的特例。
使用fscanf从文件指针in_fp进行读取时,可以写成:

fscanf(in_fp,“%c",&a);

而如果写

fscanf(stdin"%c",&a );

这将完全与下面直接使用scanf的方式等价。

scanf("%c", &a) ;

类似地,使用fprintf向文件指针out_fp进行写出时,可以写成:

fprintf(out_fp,“%c", a);

而如果写

fprintf( stdout"%c", a);

这将完全与下面直接使用printf的方式等价。

printf("%c", a);

在使用文件并且确定不再继续使用后,要通过下面所示的方式将文件指针f与文件的关联断开。
可以将它视为和fopen相反的一个操作。

fc1ose(fp);

如果不在程序中使用fclose,程序正常结束时,程序会为所有打开的文件调用fclose 。

stdin、stdout其实也是被打开的文件指针,如果觉得用不到的话,其实也是可以使用fclose将他们关闭掉的。

调试代码

通过 gdb 可以看见变量值的变化、决定程序什么时候继续执行下一步或是发现奇怪的内存访问行为

要充分的利用gdb帮助找到程序编写时候的问题,需要在编译时使用-g作为一个编译参数(否则你将看不见函数名、变量名,而只能看到运行时的内存地址),例如:

gcc -o program -g main.c

这时候,再通过

gdb ./ program

将程序在gdb提供的一个“受控制的环境”中运行起来。

这时候会看到一系列关于gdb的说明和下面这样一个等待通过命令进行调试的命令行。

 (gdb)

最基本的gdb 使用:
1、如果输入 l ( list 的首字母),gdb 会列出带着行号的10行程序,可以根据这个行号进行进一步的调试。l 之后可以加行号作为参数,列出这一行开始的10行
2、如果输入 b ( breakpoint 的首字母),则表示设置程序运行的断点,程序运行到断点时就会暂停运行。b之后既可以加函数名作为参数(例如当有一个函数名为 func 时,可以写b func),使程序在调用某一函数时暂停,也可以加行号作为参数(例如 b 5 表示在第五行设置一个断点),使程序在运行某一行时暂停。
3、如果输入r (run 的首字母),程序则会开始运行,并且暂停在设置断点的位置。
。。运行暂停时,如果输入p表达式(print 的首字母)则表示在当前断点运行这个表达式并查看它的值。例如 p ++age[0] 表示让 age[0] 自增1并查看自增后的值。注意:这个表达式会对之后的程序继续运行造成影响。
。。运行暂停时,如果输入n (next 的首字母)程序会执行暂停位置后的下一条语句并再次暂停。
。。运行暂停时,如果输入c (continue的首字母)程序会继续执行到下一关断点再暂停(如果没有断点就会执行直到结束)。

  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值