一、数据类型

常量

1、通过预处理声明常量

#include <stdio.h>

#define PRICE 100

int main() {
printf("价格:%d\n",PRICE);
return 0;
}

2、通过 const 关键字声明常量

#include <stdio.h>
const int NUM=10;
int main() {
printf("数量:%d\n",NUM);
return 0;
}

区别:#define 在运行时会替换为指定的值,const可以看到数据类型,更推荐使用 const

整型

在C语言中分为有符号和无符号整型,无符号是整数,有符号包含负数

类型 说明
short 2字节
int 4字节
long 32位系统4字节,64位系统8字节
long long 8字节
int main() {
int a=10;
int b=-10;
long long c=20;
int d=0b111;//二进制
int e=0xb;//十六进制
int f=010;//八进制
unsigned int g=12;//无符号正数
printf("a=%d,b=%d,c=%d,d=%d",a,b,c,d);
return 0;
}
  • 0b 为二进制方式赋值
  • 0x 为十六进制数据
  • 0 为八进制数据

进制相关知识参考其他教程

c11 标准 stdint.h 对数据的长度进行了统一

类型 说明
int8_t 统一8位1字节
int16_t 2字节
int32_t 4字节
int64_t 8字节
uint8_t 无字符1字节

浮点数

类型 说明
float 单精度,4字节,32位
double 双精度,8字节,64位
long double 长双精度,16字节,128位

typedef 自定义类型

typedef uint8_t mychar;
int main() {
mychar ch='a';
printf("%c",ch);
return 0;
}

自定义类型相当于对类型起了个别名

二、goto 跳转

使用 goto 实现循环

int i=0;
aa:
printf("%d\n",i);
i=i+1;
if(i<100){
goto aa;
}

标签名: 标记一个位置,goto 标签名; 跳转到指定标签位置,标签名可以自己定义。

三、输入与输出

相关函数文档参考:C语言stdio.h文档

1、字符输出

putchar:写字符到标准输出,相当于调用 putc

遍历字符并打印

#include <stdio.h>

int main() {
char c;
for (c='a';c<='z';c++) {
putchar(c);
putchar('\n');
}
return 0;
}

说明:char 类型占用1字节,每个字符都映射对应一个整数。

查看字符对应整数

#include <stdio.h>

int main() {
char c;
printf("=====小写====\n");
for (c='a';c<='z';c++) {
printf("%d\n",c);
}
printf("=====大写====\n");
for (c='A';c<='Z';c++) {
printf("%d\n",c);
}
return 0;
}

大写字符和小写字符刚好差距32, putchar('A'+32); 可转为小写。

2、字符串输出

puts:写字符串到标准输出

输出字符串示例

#include <stdio.h>

int main() {
char string [] = "Hello world!";
puts(string);
return 0;
}

3、格式化输出

printf:打印格式化数据到标准输出,如果包含格式说明符(以%开头的子串)将格式化,用附加参数替换说明符(说明符可以认为是占位符)。

格式化时用到的说明符

符号 解释 举例
d 或者 i 有符号十进制整数 392
u 无符号十进制整数 7235
o 无符号八进制 610
x 无符号十六进制整数 7fa
X 无符号十六进制整数(大写) 7FA
f 十进制浮点,小写 392.65
F 十进制浮点,大写 392.65
e 科学记数法(尾数/指数),小写 3.9265e+2
c 字符 a
s 字符串 hello
p 指针地址(内存地址) b8000000
% %%打印出一个% %

格式化输出示例

#include <stdio.h>

int main() {
printf("字符:%c %c\n",'a',65);
printf("整数:%d %ld\n",600,6500000L);//%ld 长整
printf("浮点数:%f\n",33.3);
printf("十六进制:%x\n",0xffa);
printf("特殊打印:%%\n");
return 0;
}

结果

字符:a A
整数:600 6500000
浮点数:33.300000
十六进制:ffa
特殊打印:%

4、输入字符和字符串

getchar:从标准输入中获取字符

获取字符示例

#include <stdio.h>

int main() {
uint8_t c;
puts("输入文本,在一个句子中包含.以结束:");
do{
c=getchar();
putchar(c);
}while (c!='.');
return 0;
}

uint8_t c; uint8_t 大小与char一样

gets:从标准输入中获取字符串

获取字符串示例

#include <stdio.h>

int main() {
char str[256];
puts("输入你的名字:");
gets(str);
printf("你的名字:%s\n",str);
return 0;
}

5、格式化输入

scanf:从标准输入中读取格式化数据,格式化说明符可参照 printf

格式化输入示例

#include <stdio.h>

int main() {
char ch;
int num;
char str[10]; puts("输入一个字符:");
scanf("%c",&ch);
printf("用户的输入字符为:%c\n",ch); puts("输入一个整数:");
scanf("%d",&num);
printf("用户输入的整数为:%d\n",num); puts("输入字符串:");
scanf("%s",str);
puts(str);
return 0;
}

int、char 等类型需要用&符号取得变量内存地址,变量 str 是一个数组,本身存储的就是内存地址,所以不用加上&符号。(可以理解为值与引用)

四、数组

1、一维数组

创建数组方式1:

const int NUMS_LEN=10;
int nums[NUMS_LEN];

数组中元素的内存地址没有做过任何处理,有可能被之前其他程序使用过,所以数组中的默认的值是不可预期的。

演示数组中元素默认值:

#include <stdio.h>

int main() {
const int NUMS_LEN=10;
int nums[NUMS_LEN];
for (int i = 0; i < NUMS_LEN; ++i) {
printf("索引:%d,值:%d\n",i,nums[i]);
}
return 0;
}

创建数组方式2:

int ages[]={19,20,30};

2、二维数组

创建方式1:

int nums[3][4];
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 4; ++j) {
printf("%d,%d,value=%d\n",i,j,nums[i][j]);
}
}

创建方式2:

int nums[2][3]={
{1,2,3},
{4,5,6}
};

二维数组直接初始化值需要指定长度!

如果想对数组中的元素清0,可以在遍历中为元素赋值为0.

3、字符数组(字符串)

声明字符串并检查长度:

char str[10];
printf("长度:%ld\n",strlen(str));

strlen 函数用于检测字符数组中字符的长度

存入字符串并检查长度:

char str[10]="hello";
printf("长度:%ld\n",strlen(str));

\0作为字符串结尾:

char str[10]="he\0llo";
printf("长度:%ld\n",strlen(str));

字符串中不论内容多少,只要遇到 \0 就认为字符串结束!

char数组填充函数 memset:

memset(要填充的数组,要填充的值,要填充多长)

#include <stdio.h>
#include <string.h>
int main() {
char str[]="你好";
memset(str,1,6);
for (int i = 0; i < 6; ++i) {
printf("%d\n",str[i]);
}
return 0;
}

关于中文:

char str[2]="你好";
printf("长度:%ld\n",strlen(str));//一个汉字占用3字节

五、字符串操作

1、字符串连接

strcat:连接字符串,将源字符串的副本附加到目标字符串。

#include <stdio.h>
#include <string.h>
int main() {
char * str="hello";//要拼接的字符
char result[100];//目标字符
memset(result,0,100);//填充0到目标字符
strcat(result,str);//拼接str到result
strcat(result,"world");//拼接 world 到result
puts(result);
return 0;
}

strncat:连接指定数量的字符到目标字符串

#include <stdio.h>
#include <string.h>
int main() {
char dist[10];
strncat(dist,"hello",3);
puts(dist);
return 0;
}

结果

hel

2、格式化字符串

sprintf:将格式化数据写入字符串(格式方式和其他格式化方法很像)

#include <stdio.h>
#include <string.h>
int main() {
char str[10];
memset(str,0,10);
int len,a=10,b=5;
len=sprintf(str,"%d+%d=%d",a,b,a+b);
printf("格式结果:[%s],长度为:%d",str,len);
return 0;
}

结果:

格式结果:[10+5=15],长度为:7

3、字符串与基础数据类型转换

sscanf:从字符串中读取格式化数据

使用 sscanf 截取数据

#include <stdio.h>
#include <string.h>
int main() {
//原字符串
char sentence[]="Java is 23 years old";
//保存拆分出来的数据的变量
int age;
char name[10];
sscanf(sentence,"%s %*s %d",name,&age);
printf("age is %d,name is %s",age,name);
return 0;
}

"%s %*s %d" 分别表示了 Java is 23 (空格也包含在内),%*s 表示匹配的字符串但忽略该数据(可以理解占了个位置)。&age 这里需要将基本类型的内存地址引入。

使用 sscanf 转换数据类型

#include <stdio.h>
int main() {
char * str="100";
int a;
sscanf(str,"%d",&a);
printf("转换后:%d",a);
return 0;
}

使用 atof 将字符串转为 double

#include <stdio.h>
#include <stdlib.h>
int main() {
double result=atof("3.14");
printf("转换后:%f",result);
return 0;
}

4、字符串比较

== 用来比较两个变量的内存地址,不能比较字符串的值。使用 strcmp 比较两个字符串的值,两个字符串的值相等返回 0。

#include <stdio.h>
#include <string.h>
int main() {
char * str1="hello";
char str2[]="hello";
if(strcmp(str1,str2)==0){
puts("两个字符串的值相等");
}else{
puts("两个字符串的值不相等");
}
return 0;
}

5、字符串的截取

strchr:从指定字符开始截取

#include <stdio.h>
#include <string.h>
int main() {
char * str="helloworld";
char * result=strchr(str,'w');
puts(result);
return 0;
}

strrchr:从最后一个指定字符开始截取

#include <stdio.h>
#include <string.h>
int main() {
char * str="helloworld";
char * result=strrchr(str,'l');
puts(result);
return 0;
}

strstr:从指定字符串开始截取

#include <stdio.h>
#include <string.h>
int main() {
char * str="helloworld";
char * result=strstr(str,"wo");
puts(result);
return 0;
}

区分大小写

strncpy:从字符串中复制指定长度字符

#include <stdio.h>
#include <string.h>
int main() {
char * str="helloworld";
char dest[10];
strncpy(dest,str,5);
puts(dest);
return 0;
}

使用指针从指定位置开始截取

#include <stdio.h>
#include <string.h>
int main() {
char * str="helloworld";
char * str1=str+5;
puts(str1);
return 0;
}

可以先利用指针操作从某个位置开始截取,然后利用 strncpy 截取指定个。

六、函数

声明和调用的方式和java很相似

1、main 函数的参数

main 函数的参数,也是程序运行时的参数

声明时需指定:1.参数的长度,2.参数数组

#include <stdio.h>
int main(int argc,char ** argv) {
printf("参数的个数:%d\n",argc);
for (int i = 0; i < argc; ++i) {
printf("参数 %d 的值:%s\n",i,argv[i]);
}
return 0;
}

2、可变参数

#include <stdio.h>
#include <stdarg.h>
void testarg(int n,...){
printf("参数的个数:%d\n",n);
va_list args;
va_start(args,n);
for (int i = 0; i < n; ++i) {
int temp=va_arg(args,int);
printf("参数:%d\n",temp);
}
va_end(args);
}
int main(int argc,char ** argv) {
testarg(2,10,55);
return 0;
}

函数设置可变参数时需指定参数个数形参 int n ,和 ...(任意个数的参数)。需引入头文件 stdarg.h,va_list 类型保存有关变量参数的信息,va_start 初始化变量参数列表,va_arg 取出参数的值,va_end 结束使用变量参数列表

七、预处理

1、预设常量

除了可以用 #define 定义一个常量,还可以在编译参数中指定预设常量的值

编写没有声明常量但使用了常量的代码

#include <stdio.h>

int main() {
printf("The num is %d\n",THE_NUM);
return 0;
}

使用命令进行编译和运行

gcc -o test main.c -DTHE_NUM=4
test.exe

-o 参数指定编译后可执行文件的文件名,-D 参数后面直接跟常量名和值(没有空格)

2、编译条件针对不同平台编译

1.编写代码

#include <stdio.h>

#define WIN 1
#define LINUX 2
#define MAC 3 int main() {
#if PLATFORM==WIN
printf("Hello Windows\n");
#elif PLATFORM==LINUX
printf("Hello Linux\n");
#elif PLATFORM==MAC
printf("Hello MAC\n");
#else
printf("Unknow platform\n");
#endif
return 0;
}

if、#elif、#else、#endif 这些都是编译条件,用于决定代码块是否编译

2.编译时指定条件

//编译源码
gcc -o test main.c -DPLATFORM=1
//运行
test.exe

3、头文件重复引入

1、演示重复引入

1.创建a.h

#include "b.h"

2.创建b.h

#include "a.h"

3.引入a.h

#include <stdio.h>
#include "a.h"
int main() { return 0;
}

2、防止头文件重复引入

修改a.h

#ifndef A_H
#define A_H
#include "b.h"
#endif

修改b.h

#ifndef B_H
#define B_H
#include "a.h"
#endif

通过标记一个常量来判断是否重复引入,一旦拥有这个常量将不再引入

八、指针

声明一个变量后,系统会为这个变量分配内存空间,每个变量都有一个内存地址,相当于旅馆的房间号。

我们要获取变量中的值需要通过内存地址来找到对应的值,但是还有另一种情况是这个变量中存放的是另个一变量的内存地址。这就好像你通过房间号找到这个房间,发现在这个房间里面是另一个房间的房间号。

所以,一个变量的地址就成为该变量的指针

声明指针并指向一个变量的地址

#include <stdio.h>
int main() {
int *a,*b;
int i=10;
a=&i;
b=&i;
printf("a的值为:%d\n",*a);
printf("b的值为:%d\n",*b);
i=99;
printf("a的值为:%d\n",*a);
printf("b的值为:%d\n",*b);
return 0;
}

C语言用*表示指针,为指针赋值时 & 取出变量的地址。(指针a和指针b指向同一个地址,修改i后指针中的也会改变,这个很类似Java和C#中的引用类型)

指针的大小

#include <stdio.h>
int main() {
int *a;
printf("size is %ld\n", sizeof(a));
return 0;
}

64位系统中为8字节,32位中为4字节

1、函数指针

有参无返回值的函数指针

#include <stdio.h>

void hello(int a,char* c){
printf("hello\n");
}
int main() {
void(*fp)(int,char*)=&hello;
fp(1,"");
return 0;
}

有参有返回值的函数指针

#include <stdio.h>

int test(int a){
printf("hello:%d\n",a);
return a;
}
int main() {
int(*fp1)(int)=&test;
int result=fp1(11);
printf("返回值:%d\n",result);
return 0;
}

给函数指针设定类型别名

#include <stdio.h>

void hello(){
printf("Hello\n");
}
typedef void(*SimpleHello)();
int main() {
SimpleHello h1=&hello;
h1();
SimpleHello h2=&hello;
h2();
return 0;
}

重复定义时可以简化代码

2、无类型指针

无类型指针可以代表所有类型的数据

无类型指针存放字符串

#include <stdio.h>

int main() {
void *test="Hello";
printf("%s\n",test);
return 0;
}

九、结构体与共同体

1、结构体

主要用结构体描述属性

定义使用结构体

#include <stdio.h>
struct File{
char* name;
int size;
};
int main() {
struct File file;
file.name="a.txt";
file.size=10;
printf("文件 %s 的大小为 %d\n",file.name,file.size);
struct File file1={"a.jpg",100};
printf("文件 %s 的大小为 %d\n",file1.name,file1.size);
return 0;
}

结构体也可以像数组那样初始化(C#中也有结构,两者比较像可以对比记忆)

定义结构体类型简化代码

#include <stdio.h>
typedef struct _File{
char* name;
int size;
}File;
int main() {
File file;
file.name="a.txt";
file.size=10;
printf("文件 %s 的大小为 %d\n",file.name,file.size);
File file1={"a.jpg",100};
printf("文件 %s 的大小为 %d\n",file1.name,file1.size);
return 0;
}

2、结构体的内存对齐

结构体所占大小如何计算的?结构的大小由各变量与字节最大变量对齐后相加得出。

如图所示,三种情况:

1.当定义第一个变量大小为1字节,第二个变量比第一个变量大时,第一个变量要对齐大的变量,第一个变量填充为2字节,结构体大小为4字节。

2.前两变量加起来不足对齐第三个变量的大小,所以填充2字节对齐,结构体大小为8字节。

3.前4个变量加起来刚好对齐第5个变量的大小,无须对齐。最后一个变量没有对齐则填充2个字节对齐第5个变量,所以结构体大小为12字节。

#include <stdio.h>

typedef struct _Data{
uint8_t a;//1
uint8_t b;//1
uint8_t c;//1
uint8_t d;//1
uint32_t e;//4
uint8_t f;//1
}Data;
int main() {
printf("size is %d\n", sizeof(Data));
return 0;
}

此时结果为12

3、结构体指针

没有使用指针前

#include <stdio.h>
typedef struct _Dog{
char * color;
int age;
}Dog;
int main() {
Dog dog1={"红色",2};
Dog dog2=dog1;
dog1.age=3;
printf("(dog1 color is %s,age is %d),(dog2 color is %s,age is %d)\n"
,dog1.color,dog1.age,dog2.color,dog2.age
);
return 0;
}

没有使用之前将dog1赋值给dog2相当于复制一个副本

使用结构体指针

#include <stdio.h>

typedef struct _Dog {
char *color;
int age;
} Dog; int main() {
Dog dog1 = {"红色", 2};
Dog *dog2 = &dog1;
dog1.age = 3;
printf("(dog1 color is %s,age is %d),(dog2 color is %s,age is %d)\n",
dog1.color, dog1.age, dog2->color, dog2->age);
return 0;
}

指针操作用法和之前一样,需要注意的地方是:结构体指针,获取结构体的值时需要使用 -> ,否则将编译错误

通过函数创建和销毁结构体指针

#include <stdio.h>
#include <stdlib.h> typedef struct _Dog {
char *color;
int age;
} Dog;
Dog* createDog(char* color,int age){
Dog* dog=malloc(sizeof(Dog));
dog->color=color;
dog->age=age;
return dog;
}
void deleteDog(Dog* dog){
free(dog);
} int main() {
Dog* dog1=createDog("红色",3);
printf("(dog1 color is %s,age is %d)\n",
dog1->color, dog1->age);
deleteDog(dog1);
return 0;
}

malloc函数分配内存,使用完毕后用free函数释放内存(释放后的内存的值不可预期何时修改,free函数调用后别的程序就可以使用这块空间了)

3、共同体

共同体的特点:共同体中声明的所有变量共用一块空间

声明及使用共同体

#include <stdio.h>
typedef union _BaseData{
char ch;
uint8_t ch_num;
}BaseData;
int main() {
BaseData data;
data.ch='A';
printf("ch_num is %d size is %d\n",data.ch_num, sizeof(BaseData));
return 0;
}

变量 ch_num 和 ch 共用同一内存地址,大小为 1,共同体做类型转换比较方便。

实现颜色的操作

#include <stdio.h>
//定义颜色结构体
typedef struct _ColorARGB{
uint8_t blue;
uint8_t green;
uint8_t red;
uint8_t alpha;
}ColorARGB;
//定义颜色共同体
typedef union _Color{
uint32_t color;
ColorARGB colorARGB;
}Color;
int main() {
Color c;
c.color=0xFFAADD00;
printf("red:%X",c.colorARGB.red);
return 0;
}

存入的数据是以小端模式,所以定义颜色结构体时的通道的顺序和赋值的颜色顺序相反。结合结构体与共同体实现(巧妙)

十、文件操作

fopen函数:以指定文件名和模式获取一个流的FILE指针。

支持的模式

模式 说明
"r" 读:文件必须存在
"w" 写:创建一个文件,如果已经存在则覆盖
"a" 追加:向文件末尾追加内容,如果文件不存在则创建该文件
"r+" 可做读取和修改的操作,文件必须存在

写文件

//创建文件指针
FILE * file=fopen("a.txt","w");
if (file){
//写入内容
fputs("HelloWorld",file);
//关闭
fclose(file);
}else{
puts("文件操作失败!");
}

读文件

#include <stdio.h>
int main() {
FILE * file=fopen("a.txt","r");
if (file){
char ch;
while(1){
ch=fgetc(file);
if(ch!=EOF){
printf("%c\n",ch);
}else{
break;
}
}
fclose(file);
}
return 0;
}

C语言入门语法的更多相关文章

  1. Go 语言入门(一)基础语法

    写在前面 在学习 Go 语言之前,我自己是有一定的 Java 和 C++ 基础的,这篇文章主要是基于A tour of Go编写的,主要是希望记录一下自己的学习历程,加深自己的理解 Go 语言入门(一 ...

  2. 《JavaScript语言入门教程》记录整理:运算符、语法和标准库

    目录 运算符 算数运算符 比较运算符 布尔运算符 二进制位运算符 void和逗号运算符 运算顺序 语法 数据类型的转换 错误处理机制 编程风格 console对象和控制台 标准库 Object对象 属 ...

  3. Swift语言入门之旅

    Swift语言入门之旅  学习一门新的计算机语言,传统来说都是从编写一个在屏幕上打印"Hello world"的程序開始的.那在 Swift,我们使用一句话来实现它: printl ...

  4. 《Ruby语言入门教程v1.0》学习笔记-01

    <Ruby语言入门教程v1.0> 编著:张开川 邮箱:kaichuan_zhang@126.com 想要学习ruby是因为公司的自动化测试使用到了ruby语言,但是公司关于ruby只给了一 ...

  5. C语言入门(1)——C语言概述

    1.程序与编程语言 我们使用计算机离不开程序,程序告诉计算机应该如何运行.程序(Program)是一个精确说明如何进行计算的指令序列.这里的计算可以是数学运算,比如通过一些数学公式求解,也可以是符号运 ...

  6. PBFT概念与Go语言入门(Tendermint基础)

    Tendermint作为当前最知名且实用的PBFT框架,网上资料并不很多,而实现Tendermint和以太坊的Go语言,由于相对小众,也存在资料匮乏和模糊错漏的问题.本文简单介绍PBFT概念和Go语言 ...

  7. 初识 go 语言:语法

    目录 语法 for 循环 if 语句 switch 语句 defer 语句 defer 栈 结束 前言: go语言系列第二篇,主要讲述go语言的语法,如循环,if判断,swich语句,defer语句, ...

  8. Groovy语言学习--语法基础(5)

    至此groovy语言学习-语法基础就结束了,新的工作已经安排下来,要干活了. 对groovy了解到一定程度之后就可以在java项目中对其进行引入了.为此新建了一个微型的项目,个人觉得千言万语不如代码实 ...

  9. C语言入门教程-(5)格式化输入输出

    1.输入和输出 在程序的使用中,我们经常可以看的这么一个场景:用户需要输入数据,经过程序运算,得到结果后输出.在C语言中,输入数据和输出数据都是由库函数完成的,通过语句来输入/输出. 2.格式化输出— ...

随机推荐

  1. 一些参考网站 - Reference Documentation - Website Address

    Reference Documentation - Website Address MSDN Visual Studio 2015官方文档 https://msdn.microsoft.com/zh- ...

  2. Transaction And Lock--解决死锁/锁的几种有效方式

    修改资源访问顺序,使多个事务对资源的访问方式一致优化查询SELECT,使得S锁能尽早释放均可能将更新和删除语句放到事务末端(使得X锁占用时间最小)避免事务执行期间暂停或等待外部输入将较大事务拆分成多个 ...

  3. Spring MVC 基本配制

    WEB.XML 文件中的配制: <?xml version="1.0" encoding="UTF-8"?> <web-app id=&quo ...

  4. mysql 循环插入

    在mysql添加测试数据,想和mssql一样用循环实现,发现不管怎么样都执行失败 经查询发现mysql不支持匿名块,只能先创建出一个存储过程,执行,然后删除 CREATE PROCEDURE test ...

  5. 一文读懂加固apk的开发者是怎么想的

    有人说加固会明显拖慢启动速度,同时造成运行卡顿,严重降低用户体验,而且加固是完全可以脱壳的,只需要pc配合进行断点调试就能抓到解密后的dex文件,加固并没有所说的那么安全. 但是为什么还有一大批开发者 ...

  6. SnowFlake 生成全局唯一id

    public class SnowFlakeUtil { private long workerId; private long datacenterId; private long sequence ...

  7. TOMCAT在POST方法提交参数丢失问题

    最近写程序发现post参数接收不到了,jdk,eclipse,jar包,换了多次都不行,后来看到网上一篇文章: 随后设置Tomcat中POST方式提交数据大小: maxPostSize="0 ...

  8. esp32编程第一例 hollow word

    #include<stdio.h>#include"freertos/FreeRtos.h"#include"freertos/task.h"#in ...

  9. SimpleITK学习(二)图像读取

    通常我会用simpleitk来读取dicom文件,主要是为了将dicom文件转换为numpy矩阵,便于输入神经网络,读取dicom文件可分为两种情况,一.单独的dicom文件 二.一系列dicom文件 ...

  10. 用servlet校验密码

    一.结果图 package Login; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connect ...