文档章节

C程序设计语言--第七章:输入与输出

fzyz_sb
 fzyz_sb
发布于 2013/10/02 19:52
字数 2941
阅读 125
收藏 0
点赞 0
评论 0

7.1 标准输入/输出

最简单的输入机制是使用getchar函数从标准输入中(一般为键盘)一次读取一个字符:

int getchar( void );
getchar函数在每次被调用时返回下一个输入字符.若遇到文件结尾,则返回EOF.

在许多环境中,可以使用符号<来实现输入重定向,它将把键盘输入替换为文件输入:如果程序prog中使用了函数getchar,则命令行

prog <infile
将使得程序prog从输入文件infile(而不是键盘)中读取字符.如果输入通过管道机制来自于另一个程序,那么这种输入切换也是不可见的.比如:
otherprog | prog
将运行两个程序otherprog和prog,并将程序otherprog的标准输出通过管道重定向到程序prog的标准输入上.

函数

int putchar( int )
用于输出数据.putchar(c)将字符c送至标准输出上.在默认情况下,标准输出为屏幕显示.如果没有发生错误,则函数putchar将返回输出的字符;如果发生错误,则返回EOF.当然,我们也可以用重定向字符>:
prog > outfile
将把程序prog的输出从标准输出设备重定向到文件中.

习题7-1:

#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main( int argc, char *argv[] )
{
	int ch;
	if ( strcmp( argv[ 1 ], "lower" ) == 0 ){	//argv[0]是运行程序的名称
		while ( ( ch = getchar() ) != EOF ){
			putchar( tolower( ch ) );
		}
	}
	else{
		while ( ( ch = getchar() ) != EOF ){
			putchar( toupper( ch ) );
		}
	}
}
程序输出:

7.2 格式化输出----printf函数

int printf( char *format, arg1, arg2,...)
函数printf在输出格式format的控制下,将其参数进行转换与格式化,并在标准输出设备上打印出来.它的返回值为打印的字符数.

在字符%和转换字符中间可能依次包含下列组成部分:

1. 负号:用于指定被转换的参数按照左对齐的形式输出

2. 数: 用于指定最小字段宽度.转换后的参数将打印不小于字段宽度的字段.如果有必要,字段左边(如果使用左对齐的方式,则为右边)多余的字符位置用空格填充以保证最小字段宽.

3. 小数点: 用于将字段宽度和精度分开.

4. 数,用于指定精度,即指定字符串中要打印的最大字符数,浮点数小说点后的位数,整型最少输出的数字数目

5. 字符h或l,字母h表示将证书作为short类型打印,字母l表示将证书作为long类型打印.

在转换说明中,宽度或精度可以用星号*表示,这时,宽度或精度的值通过转换下一参数(必须为int类型)来计算.例如,为了从字符串s中打印最多max个字符,则可以这样写:

printf("%.*s", max, s );
函数sprintf执行的转换和函数printf相同,但它将输出保存到一个字符串中:
int sprintf( char *string, char *format, arg1, arg2,...)
这里最好保证string的空间够大:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

int main( void )
{
	char str[10];
	memset( str, 0, 10 );
	sprintf(str, "%s%s", "hello", "--world" );

	printf("%s\n", str );

	return 0;
}
运行这个程序,则会发现:错误.........

7.3 变长参数表

我们编写一个类似printf函数的minprintf.

标准头文件<stdarg.h>中包含一组宏定义,它们对如何遍历参数表进行了定义.

va_list类型用于声明一个变量,该变量将依次引用各参数.在函数minprintf中,我们将该变量称为ap,意思是"参数指针".宏va_start将ap初始化为指向第一个无名参数的指针.在使用ap之前,该宏必须被调用一次.参数表必须至少包括一个有名参数,va_start将最后一个有名参数作为起点.

每次调用va_arg,该函数都将返回一个参数,并将ap指向下一个参数.va_arg使用一个类型名来决定返回的对象类型,指针移动的步长.最后,必须在函数返回之前调用va_end,以完成一些必要的清理工作.

#include <stdarg.h>
#include <stdio.h>

void minprintf( char *fmt, ...)
{
	va_list ap;
	char *p, *sval;
	int ival;
	double dval;

	va_start( ap, fmt );
	for ( p = fmt; *p; p++ ){
		if ( *p != '%' ){
			putchar( *p );
			continue;
		}
		switch( *++p ){
			case 'd':
				ival = va_arg( ap, int );
				printf("%d", ival );
				break;
			case 'f':
				dval = va_arg( ap, double );
				printf("%f", dval );
				break;
			case 's':
				for ( sval = va_arg( ap, char * ); *sval; sval++ ){
					putchar( *sval );
				}
				break;
			default:
				putchar( *p );
				break;
		}
	}
	va_end( ap );
}

int main( void )
{
	minprintf("%d %f %s\n", 12, 12.345, "hello world" );

	return 0;
}
程序输出:

习题7-3:

还是冒昧的用到了printf来指定输出:

#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

void minprintf( char *fmt, ...)
{
	va_list ap;
	char *p, *sval;
	int ival;
	double dval;
	int isLeft = 0;	//是否左对齐
	int width = 0;		//宽度
	int precision = 0;	//精度
	int isDot = 0;		//判断存在小数点

	va_start( ap, fmt );
	for ( p = fmt; *p; p++ ){
		if ( *p != '%' ){
			putchar( *p );
			continue;
		}
		if ( *++p ){
			if ( '-' == *p ){
				isLeft = 1;
				p++;
			}
			if ( isdigit( *p ) ){
				width = *p - '0';
				p++;
			}
			if ( '.' == *p ){
				p++;
				isDot = 1;
			}
			if ( isdigit( *p ) ){
				precision = *p - '0';
				p++;
			}
			if ( 'd' == *p ){
				ival = va_arg( ap, int );
				if ( isLeft ){
					printf( "%-*.*d", width, precision, ival );
				}
				else{
					printf( "%*.*d", width, precision, ival );
				}
			}
			else if ( 'f' == *p ){
				dval = va_arg( ap, double );
				if ( isLeft ){
					if ( precision ){
						printf( "%-*.*f", width, precision, dval );
					}
					else{
						if ( isDot ){
							printf("%-*.f", width, dval );
						}
						else{
							printf("%-f", dval );
						}
					}
				}
				else{
					if ( precision ){
						printf( "%*.*f", width, precision, dval );
					}
					else{
						if ( isDot ){
							printf("%*.f", width, dval );
						}
						else{
							printf("%f", dval );
						}
					}
				}
			}
			else if ( 's' == *p ){
				sval = va_arg( ap, char * );
				if ( isLeft ){
					if ( precision ){
						printf("%-*.*s", width, precision, sval );
					}
					else{
						if ( isDot ){
							printf("%-*.s", width, sval );
						}
						else{
							printf("%-s", sval );
						}
					}
				}
				else{
					if ( precision ){
						printf("%*.*s", width, precision, sval );
					}
					else{
						if ( isDot ){
							printf("%*.s", width, sval );
						}
						else{
							printf("%s", sval );
						}
					}
				}
			}
			else{
				putchar( *p );
				isLeft = 0;
				width = 0;
				precision = 0;
			}
		}
	}
	va_end( ap );
}

int main( void )
{
	minprintf("%d\n", 123 );
	minprintf("%-9.8d\n", 1234567 );
	minprintf("%-9.8f\n", 1234.5678 );
	minprintf("%-.8f\n", 1234.5678 );
	minprintf("%s\n", "hello world" );
	minprintf("%.5s\n", "hello world" );


	return 0;
}
程序输出:

7.4 格式化输入---scanf函数

这道题的精髓在于:把地址进行传递:

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAXLINE 128

char *getword( char *line, char *word )
{
	int i = 0;
	while ( !isalnum( *line ) ){
		line++;
	}
	while ( isalnum( *line ) ){
		word[ i++ ] = *line++;
	}
	if ( '.' == *line ){
		word[ i++ ] = '.';
		line++;
	}
	while ( isalnum( *line ) ){
		word[ i++ ] = *line++;
	}

	while ( isspace( *line ) && '\n' != *line ){
		line++;
	}

	word[ i ] = '\0';
	return line;
}

void minscanf( char *fmt, ...)
{
	va_list ap;
	char *p;
	int index = 0;
	int *pint = NULL;
	double *pdouble = NULL;
	char **pstr = NULL;
	char *line = ( char * )malloc( sizeof( char ) * MAXLINE );
	char *word = ( char * )malloc( sizeof( char ) * MAXLINE );
	char *wordArr[ MAXLINE ];
	memset( line, 0, MAXLINE );
	memset( word, 0, MAXLINE );
	memset( wordArr, 0, MAXLINE );
	if ( NULL != fgets( line, MAXLINE, stdin ) ){
		while ( ( *line != '\n' ) && ( line = getword( line, word ) ) ){
			int i = 0;
			char *tempWord = ( char * )malloc( sizeof( char ) * MAXLINE );
			memset( tempWord, 0, MAXLINE );
			while ( '\0' != *word ){
				tempWord[ i++ ] = *word++;
			}
			tempWord[ i ] = '\0';
			wordArr[ index++ ] = tempWord;
		}
	}

	index = 0;
	va_start( ap, fmt );
	for ( p = fmt; *p; p++ ){
		if ( *p != '%' ){
			continue;
		}
		switch ( *++p ){
			case 'd':
				pint = va_arg( ap, int * );
				*pint = atoi( wordArr[ index++ ] );
				break;
			case 'f':
				pdouble = va_arg( ap, double * );
				*pdouble = atof( wordArr[ index++ ] );
				break;
			case 's':
				pstr = va_arg( ap, char ** );
				*pstr = wordArr[ index++ ];
				break;
			default:
				break;
		}
	}

	va_end( ap );
}

int main( void )
{
	int iValue;
	double dValue;
	char *sValue;
	minscanf("%d%f%s", &iValue, &dValue, &sValue );

	printf("%d\n", iValue );
	printf("%f\n", dValue );
	printf("%s\n", sValue );

	return 0;
}
程序输出:

我稍微看了下答案,发现答案把问题复杂化了,完全按照书上的思想来写...其实有点误人子弟的意思.

习题7-5:

对于这道习题,我的想法是通过getline来读取一行,然后通过sscanf来把需要计算的数分别进行存放,但是用sscanf这类操作后,程序变复杂了,因为最终都要用到堆栈的思想,就是我们通过sscanf把书提取出来,最后还是放在堆栈中----而之前写过直接从getline读取后放在堆栈中,故这道题就不做了.

7.5 文件访问

假设我们写个类似于unix系统中cat的函数:

cat x.c y.c
将在标准输出上打印文件x.c和y.c的内容.
FILE *fp;
FILE *fopen(char *name, char *mode );
fp = fopen( name, mode );
fp是一个指向结构FILE的指针,并且,fopen函数返回一个指向结构FILE的指针,该指针成为"文件指针",它指向一个包含文件信息的结构,这些信息包括:缓冲区的位置,缓冲区中当前字符的位置,文件的读或写状态,是否出错或是否已经到达文件结尾等等.

fp的第一个参数是一个字符串,包含文件名.第二个参数是访问模式,为"r","w","a".如果为二进制文件,则在访问模式后面增加"b".如果打开错误,放回NULL.

当文件打开的时候,我们需要通过getc和putc函数进行操作:

int getc( FILE *fp );
getc函数放回fp指向的输入流中的下一个字符.如果到达文件尾或出现错误,该函数返回EOF.
int putc( int c, FILE *fp );
将字符c写入到fp指向的文件中,并返回写入的字符.如果发生错误,则返回EOF.

启动一个C语言程序时,操作系统环境负责打开3个文件,并将这3个文件的指针提供给该程序.这3个文件分别是标准输入,标准输出和标准错误,相应的文件指针分别是stdin,stdout和stderr.我们可以将stdin和stdout重定向到文件或管道.

这样的话,getchar和putchar函数可以通过getc,putc,stdin,stdout定义如下:

#define getchar() getc( stdin )
#define putchar( c ) putc( ( c ), stdout )
对于文件的格式化输入或输出,可以使用函数fscanf和fprintf.它们与scanf和printf函数的区别仅仅在于它们的第一个参数是一个指向所要读写的文件的指针,第二个参数是格式串.
int fscanf( FILE *fp, char *format, ...)
int fprintf( FILE *fp, char *format, ...)
这样的话,我们就可以写出cat函数了:
#include <stdio.h>

int main( int argc, char *argv[] )
{
	FILE *fp;
	void filecopy( FILE *, FILE * );

	if ( argc == 1 ){
		filecopy( stdin, stdout );
	}
	else{
		while ( --argc > 0 ){
			if ( ( fp = fopen( *++argv, "r" ) ) == NULL ){
				printf(" cat: can't open %s\n", *argv );
				return 1;
			}
			else{
				filecopy( fp, stdout );
				fclose( fp );
			}
		}
	}

	return 0;
}

void filecopy( FILE *ifp, FILE *ofp )
{
	int c;
	while ( ( c = getc( ifp ) ) != EOF ){
		putc( c, ofp );
	}
}
不过,在window下运行的时候,提示无法打开x.c,貌似权限不够.

7.6 错误处理

用一个程序说明错误处理:

#include <stdio.h>

int main( int argc, char *argv[] )
{
	FILE *fp;
	void filecopy( FILE *, FILE * );
	char *prog = argv[ 0 ];

	if ( argc == 1 ){
		filecopy( stdin, stdout );
	}
	else{
		while ( --argc > 0 ){
			if ( ( fp = fopen( *++argv, "r" ) ) == NULL ){
				fprintf( stderr, "%s: can't open %s\n", prog, *argv );
				exit( 1 );
			}
			else{
				filecopy( fp, stdout );
				fclose( fp );
			}
		}
	}

	if ( ferror( stdout ) ){
		fprintf( stderr, "%s:error writing stdout\n", prog );
		exit( 2 );
	}

	exit( 0 );
}

void filecopy( FILE *ifp, FILE *ofp )
{
	int c;
	while ( ( c = getc( ifp ) ) != EOF ){
		putc( c, ofp );
	}
}
7.7 行输入和行输出

我们来看fgets和fputs的源代码即可:

char *fgets( char *s, int n, FILE *iop )
{
	register int c;
	register char *cs;

	cs = s;
	while ( --n > 0 && ( c = getc( iop ) ) != EOF ){
		if ( ( *cs++ = c ) == '\n' ){
			break;
		}
	}
	*cs = '\0';

	return ( c == EOF && cs == s ) ? NULL : s;
}

int fputs( char *s, FILE *iop )
{
	int c;
	while ( c = *s++ ){
		putc( c, iop );
	}

	return ferror( iop ) ? EOF : 非负值;
}
习题7-6:
#include <stdio.h>
#include <stdlib.h>

#define MAXLINE 128
int main( void )
{
	char line1[ MAXLINE ];
	char line2[ MAXLINE ];
	FILE *fp1 = fopen( "x.txt", "r" );
	FILE *fp2 = fopen( "y.txt", "r" );
	memset( line1, 0, MAXLINE );
	memset( line2, 0, MAXLINE );
	if ( NULL == fp1 || NULL == fp2 ){
		perror("file open error");
		exit( 1 );
	}
	while ( NULL != fgets( line1, MAXLINE, fp1 ) && NULL != fgets( line2, MAXLINE, fp2 ) ){
		if ( strcmp( line1, line2 ) != 0 ){
			printf("line1 is:\n%s\nline2 is:\n%s\n", line1, line2 );
			break;
		}
	}

	return 0;
}
程序输出:

习题7-8(不知道如何组织打印文件,故把答案粘贴出来.PS:这道题和cat类似而已):

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

#define		MAXBOT		3		/* maximum # lines at bottom page */
#define		MAXHDR		5		/* maximum # lines at head of page */
#define		MAXLINE		100		/* maximum size of one line */
#define		MAXPAGE		66		/* maximum # lines on one page */

int main( int argc, char *argv[] )
{
	FILE *fp;
	void fileprint( FILE *fp, char *fname );

	if ( argc == 1 ){
		fileprint( stdin, " " );
	}
	else{
		while ( --argc > 0 ){
			if ( ( fp = fopen( *++argv, "r" ) ) == NULL ){
				fprintf( stderr, "print:can't open %s\n", *argv );
				exit( 1 );
			}
			else{
				fileprint( fp, *argv );
				fclose( fp );
			}
		}
	}

	return 0;
}

void fileprint( FILE *fp, char *fname )
{
	int lineno, pageno = 1;
	char line[ MAXLINE ];
	int heading( char *fname, int pageno );
	lineno = heading( fname, pageno++ );
	while ( fgets( line, MAXLINE, fp ) != NULL ){
		if ( lineno == 1 ){
			fprintf( stdout, "\f" );
			lineno = heading( fname, pageno++ );
		}
		fputs( line, stdout );
		if ( ++lineno > MAXPAGE - MAXBOT ){
			lineno = 1;
		}
	}

	fprintf( stdout, "\f");
}

int heading( char *fname, int pageno )
{
	int ln = 3;

	fprintf( stdout, "\n\n" );
	fprintf( stdout, "%s	page %d\n", fname, pageno );
	while ( ln++ < MAXHDR ){
		fprintf( stdout, "\n" );
	}

	return ln;
}
习题7-9:
int isupper( char c )
{
	if ( c >= 'A' && c <= 'Z' ){
		return 1;
	}

	return 0;
}

#define isupper( c ) ( ( c ) >= 'A' && ( c ) <= 'Z' ) ? 1 : 0


© 著作权归作者所有

共有 人打赏支持
fzyz_sb
粉丝 404
博文 209
码字总数 447144
作品 0
武汉
程序员
做游戏,学编程(C语言) 网易云课堂MOOC视频

应一些同学的要求,把这学期上C语言编程课的讲课视频录制剪辑,上传到网易云课堂,感兴趣的朋友可以在线观看,欢迎多提宝贵意见。 MOOC视频链接:http://study.163.com/course/introduction....

童晶 ⋅ 2017/11/07 ⋅ 0

【flex&bison翻译】前言

译者注:去年的时候曾经计划翻译本书,后来终于还是抵不过懒惰,给放下了,有句经典的话:现在的努力,是为了小时候吹过的牛逼。现在体会深刻啊。。。本文是在Ubuntu 12.04.1系统下,使用Lib...

MatthewChie ⋅ 2012/08/25 ⋅ 2

JavaScript 编程精解 中文第三版 零、前言

零、前言 原文:Introduction 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 部分参考了《JavaScript 编程精解(第 2 版)》 We think we are creating the system for our own purp...

ApacheCN_飞龙 ⋅ 06/01 ⋅ 0

mac clion c语言执行不到结果,怎么回事?

mac上的clion ide中执行《c程序设计语言》中的习题,得不到直方图,输入了字符,啥都没输出,是哪块不对吗? /编写一个程序,打印输入中单词长度的直方图。水平方向的直方图比较容易绘制,垂...

莫高窟同学 ⋅ 2016/10/16 ⋅ 1

新C语言教程学习资料分享基础篇

1、C语言的发展过程 C语言是在 70 年代初问世的。一九七八年由美国电话电报公司(AT&T)贝尔实验室正式发表了C语言。同时由B.W.Kernighan和D.M.Ritchit合著了著名的“THE C PROGRAMMING LAN...

小辰带你看世界 ⋅ 01/05 ⋅ 0

C语言-第1章、 程序设计基础与C语言概述

1_3 C结构与书写规则 _3-1 C程序的基本结构 【例1-1】在屏幕上显示出一行信息: 程序成分说明: (1)注释 注释用来向用户提示或解释代码的含义,提高代码的可读性。注释分为以“//”开始的单...

南风末 ⋅ 2016/10/29 ⋅ 0

C语言程序设计->实验报告

C语言程序设计 刘凯 第一章 基本语法规则 项目一:分支语句 【实训目的】 1.掌握if语句的使用。 2.掌握switch……case语句的使用。 【实训内容】 1.输入三个整数x,y,z,请把这三个数由小到大...

五岳之巅 ⋅ 2010/06/22 ⋅ 0

程序员修炼之道

下载[不清晰]:http://pan.baidu.com/s/1pKWIKAn 6w2k 第一章:注重实效的哲学1.我的源码让猫给吃了2.软件的熵3.石头汤与煮青蛙4.足够好的软件5.你的知识资产6.交流第二章:注重实效的途径7.重复...

问题达人 ⋅ 2016/03/29 ⋅ 0

程序员修炼之道

下载[不清晰]:http://pan.baidu.com/s/1pKWIKAn 6w2k 第一章:注重实效的哲学 1.我的源码让猫给吃了 2.软件的熵 3.石头汤与煮青蛙 4.足够好的软件 5.你的知识资产 6.交流 第二章:注重实效的途...

zhchl2010 ⋅ 2016/03/27 ⋅ 1

清华大学视频课件:基于Linux的C++(自主模式)

基于Linux的C++(自主模式) 课程简介 Linux操作系统开源的特性使得其获得越来越重要的地位,而Linux系统编程也向C++程序设计者提出了更高的要求。本课程由C/C++语言的共性与特性出发,在深入...

dragonscroll ⋅ 2017/11/20 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

MySQL 数据库设计总结

规则1:一般情况可以选择MyISAM存储引擎,如果需要事务支持必须使用InnoDB存储引擎。 注意:MyISAM存储引擎 B-tree索引有一个很大的限制:参与一个索引的所有字段的长度之和不能超过1000字节...

OSC_cnhwTY ⋅ 52分钟前 ⋅ 0

多线程(四)

线程池和Exector框架 什么是线程池? 降低资源的消耗 提高响应速度,任务:T1创建线程时间,T2任务执行时间,T3线程销毁时间,线程池没有或者减少T1和T3 提高线程的可管理性。 线程池要做些什...

这很耳东先生 ⋅ 今天 ⋅ 0

使用SpringMVC的@Validated注解验证

1、SpringMVC验证@Validated的使用 第一步:编写国际化消息资源文件 编写国际化消息资源ValidatedMessage.properties文件主要是用来显示错误的消息定制 [java] view plain copy edit.userna...

瑟青豆 ⋅ 今天 ⋅ 0

19.压缩工具gzip bzip2 xz

6月22日任务 6.1 压缩打包介绍 6.2 gzip压缩工具 6.3 bzip2压缩工具 6.4 xz压缩工具 6.1 压缩打包介绍: linux中常见的一些压缩文件 .zip .gz .bz2 .xz .tar .gz .tar .bz2 .tar.xz 建立一些文...

王鑫linux ⋅ 今天 ⋅ 0

6. Shell 函数 和 定向输出

Shell 常用函数 简洁:目前没怎么在Shell 脚本中使用过函数,哈哈,不过,以后可能会用。就像java8的函数式编程,以后获取会用吧,行吧,那咱们简单的看一下具体的使用 Shell函数格式 linux ...

AHUSKY ⋅ 今天 ⋅ 0

单片机软件定时器

之前写了一个软件定时器,发现不够优化,和友好,现在重写了 soft_timer.h #ifndef _SOFT_TIMER_H_#define _SOFT_TIMER_H_#include "sys.h"typedef void (*timer_callback_function)(vo...

猎人嘻嘻哈哈的 ⋅ 今天 ⋅ 0

好的资料搜说引擎

鸠摩搜书 简介:鸠摩搜书是一个电子书搜索引擎。它汇集了多个网盘和电子书平台的资源,真所谓大而全。而且它还支持筛选txt,pdf,mobi,epub、azw3格式文件。还显示来自不同网站的资源。对了,...

乔三爷 ⋅ 今天 ⋅ 0

Debian下安装PostgreSQL的表分区插件pg_pathman

先安装基础的编译环境 apt-get install build-essential libssl1.0-dev libkrb5-dev 将pg的bin目录加入环境变量,主要是要使用 pg_config export PATH=$PATH:/usr/lib/postgresql/10/bin 进......

玛雅牛 ⋅ 今天 ⋅ 0

inno安装

#define MyAppName "HoldChipEngin" #define MyAppVersion "1.0" #define MyAppPublisher "Hold Chip, Inc." #define MyAppURL "http://www.holdchip.com/" #define MyAppExeName "HoldChipE......

backtrackx ⋅ 今天 ⋅ 0

Linux(CentOS)下配置php运行环境及nginx解析php

【part1:搭建php环境】 1.选在自己需要安装的安装包版本,wget命令下载到服务器响应目录 http://php.net/releases/ 2.解压安装包 tar zxf php-x.x.x 3.cd到解压目录执行如下操作 cd ../php-...

硅谷课堂 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部