|
| 1 | +C 中文件处理 |
| 2 | +=== |
| 3 | + |
| 4 | +在编程中,我们可能需要多次生成某些特定的输入数据。有时,仅在控制台上显示数据是不够的。要显示的数据可能非常大,在控制台上只能显示有限的数据,而且由于内存是容易丢失的,不可能一次又一次地恢复程序生成的数据。 但是,如果我们需要这样做,我们可以将其存储到本地文件系统中,该文件系统是易失的,并且每次都可以访问。 在这里,需要在 C 中处理文件。 |
| 5 | + |
| 6 | +C 中的文件处理使我们能够通过我们的 C 程序创建、更新、读取和删除存储在本地文件系统中的文件。 可以对文件执行以下操作。 |
| 7 | + |
| 8 | +- 创建新文件 |
| 9 | +- 打开现有文件 |
| 10 | +- 从文件中读取 |
| 11 | +- 写入文件 |
| 12 | +- 删除文件 |
| 13 | + |
| 14 | +## 文件处理函数 |
| 15 | + |
| 16 | +C 库中有许多函数可以打开、读取、写入、搜索和关闭文件。 文件函数列表如下: |
| 17 | + |
| 18 | +函数 | 描述 Description |
| 19 | +---- | ---- |
| 20 | +fopen() | 打开新文件或现有文件 |
| 21 | +fprintf() | 将数据写入文件 |
| 22 | +fscanf() | 从文件中读取数据 |
| 23 | +fputc() | 将一个字符写入文件 |
| 24 | +fgetc() | 从文件中读取一个字符 |
| 25 | +fclose() | 关闭文件 |
| 26 | +fseek() | 将文件指针设置到给定位置 |
| 27 | +fputw() | 将整数写入文件 |
| 28 | +fgetw() | 从文件中读取一个整数 |
| 29 | +ftell() | 返回当前位置 |
| 30 | +rewind() | 将文件指针设置为文件的开头 |
| 31 | +<!--rehype:style=width: 100%; display: inline-table;--> |
| 32 | + |
| 33 | +## 打开文件:fopen() |
| 34 | + |
| 35 | +我们必须先打开一个文件,然后它才能被读取、写入或更新。`fopen()` 函数用于打开文件。`fopen()` 的语法如下所示: |
| 36 | + |
| 37 | +```c |
| 38 | +FILE *fopen( const char * filename, const char * mode ); |
| 39 | +``` |
| 40 | +
|
| 41 | +fopen() 函数接受两个参数: |
| 42 | +
|
| 43 | +- 文件名(字符串)。 如果文件存储在某个特定位置,那么我们必须提及文件存储的路径。例如,文件名可以像“/some_folder/some_file.ext”。 |
| 44 | +- 打开文件的模式。 它是一个字符串。 |
| 45 | +
|
| 46 | +我们可以在 fopen() 函数中使用以下模式之一。 |
| 47 | +
|
| 48 | +模式 Mode | 描述 Description |
| 49 | +---- | ---- |
| 50 | +r | 以读取模式打开一个文本文件,允许读取文件。 |
| 51 | +w | 以写模式打开一个文本文件,允许写入文件。 |
| 52 | +a | 以追加模式打开一个文本文件,如果文件不存在,则会创建一个新文件。 |
| 53 | +r+ | 以读写模式打开一个文本文件,允许读写文件。 |
| 54 | +w+ | 以读写模式打开一个文本文件,允许读写文件。 |
| 55 | +a+ | 以读写模式打开一个文本文件,允许读写文件。 |
| 56 | +rb | 以读取模式打开二进制文件 |
| 57 | +wb | 以写入模式打开二进制文件 |
| 58 | +ab | 以追加模式打开二进制文件 |
| 59 | +rb+ | 以读写模式打开二进制文件 |
| 60 | +wb+ | 以读写模式打开二进制文件 |
| 61 | +ab+ | 以读写模式打开二进制文件 |
| 62 | +<!--rehype:style=width: 100%; display: inline-table;--> |
| 63 | +
|
| 64 | +
|
| 65 | +```c |
| 66 | +#include<stdio.h> |
| 67 | +void main( ) { |
| 68 | + FILE *fp; |
| 69 | + char ch; |
| 70 | + fp = fopen("file_handle.c", "r"); |
| 71 | + while (1) { |
| 72 | + ch = fgetc(fp); |
| 73 | + if (ch == EOF) |
| 74 | + break; |
| 75 | + printf("%c", ch); |
| 76 | + } |
| 77 | + fclose(fp); |
| 78 | +} |
| 79 | +``` |
| 80 | + |
| 81 | +输出,将打印文件的内容: |
| 82 | + |
| 83 | +```bash |
| 84 | +#include<stdio.h> |
| 85 | +void main( ) { |
| 86 | + FILE *fp; |
| 87 | + char ch; |
| 88 | + fp = fopen("file_handle.c", "r"); |
| 89 | + while (1) { |
| 90 | + ch = fgetc(fp); |
| 91 | + if (ch == EOF) |
| 92 | + break; |
| 93 | + printf("%c", ch); |
| 94 | + } |
| 95 | + fclose(fp); |
| 96 | +} |
| 97 | +``` |
| 98 | +
|
| 99 | +## 关闭文件:fclose() |
| 100 | +
|
| 101 | +`fclose()` 函数用于关闭文件。 对文件执行所有操作后,必须关闭该文件。`fclose()` 函数的语法如下: |
| 102 | +
|
| 103 | +```c |
| 104 | +int fclose(FILE *fp); |
| 105 | +``` |
| 106 | + |
| 107 | +## 写入文件:fprintf() |
| 108 | + |
| 109 | +`fprintf()` 函数用于将字符集写入文件。 它将格式化的输出发送到流。 |
| 110 | +
|
| 111 | +```c |
| 112 | +int fprintf(FILE *stream, const char *format [, argument, ...]) |
| 113 | +``` |
| 114 | +
|
| 115 | +```c |
| 116 | +#include <stdio.h> |
| 117 | +main() { |
| 118 | + FILE *fp; |
| 119 | + fp = fopen("file.txt", "w"); // 打开文件 |
| 120 | + fprintf(fp, "Hello file by fprintf...\n"); // 将数据写入文件 |
| 121 | + fclose(fp); // 关闭文件 |
| 122 | +} |
| 123 | +``` |
| 124 | +
|
| 125 | +## 读取文件:fscanf() |
| 126 | +
|
| 127 | +`fscanf()` 函数用于从文件中读取字符集。 它从文件中读取一个单词并在文件末尾返回 EOF。 |
| 128 | +
|
| 129 | +```c |
| 130 | +int fscanf(FILE *stream, const char *format [, argument, ...]) |
| 131 | +``` |
| 132 | +
|
| 133 | +```c |
| 134 | +#include <stdio.h> |
| 135 | +main(){ |
| 136 | + FILE *fp; |
| 137 | + char buff[255]; // 创建 char 数组来存储文件数据 |
| 138 | + fp = fopen("file.txt", "r"); |
| 139 | + while(fscanf(fp, "%s", buff)!=EOF) { |
| 140 | + printf("%s ", buff); |
| 141 | + } |
| 142 | + fclose(fp); |
| 143 | +} |
| 144 | +``` |
| 145 | +
|
| 146 | +## C 文件示例:存储员工信息 |
| 147 | +
|
| 148 | +让我们看一个文件处理示例,用于存储用户从控制台输入的员工信息。 我们将存储员工的 ID、姓名和薪水。 |
| 149 | +
|
| 150 | +```c |
| 151 | +#include <stdio.h> |
| 152 | +void main() { |
| 153 | + FILE *fptr; |
| 154 | + int id; |
| 155 | + char name[30]; |
| 156 | + float salary; |
| 157 | + fptr = fopen("emp.txt", "w+"); /* 打开文件 */ |
| 158 | + if (fptr == NULL) { |
| 159 | + printf("文件不存在 \n"); |
| 160 | + return; |
| 161 | + } |
| 162 | + printf("Enter the id\n"); |
| 163 | + scanf("%d", &id); |
| 164 | + fprintf(fptr, "Id= %d\n", id); |
| 165 | + printf("Enter the name \n"); |
| 166 | + scanf("%s", name); |
| 167 | + fprintf(fptr, "Name= %s\n", name); |
| 168 | + printf("Enter the salary\n"); |
| 169 | + scanf("%f", &salary); |
| 170 | + fprintf(fptr, "Salary= %.2f\n", salary); |
| 171 | + fclose(fptr); |
| 172 | +} |
| 173 | +``` |
| 174 | +
|
| 175 | +输出 |
| 176 | +
|
| 177 | +```bash |
| 178 | +Enter the id |
| 179 | +1 |
| 180 | +Enter the name |
| 181 | +kenny |
| 182 | +Enter the salary |
| 183 | +120000 |
| 184 | +``` |
| 185 | +
|
| 186 | +现在从当前目录打开文件。你会看到 emp.txt 文件。它有以下信息: |
| 187 | +
|
| 188 | +```bash |
| 189 | +Id= 1 |
| 190 | +Name= kenny |
| 191 | +Salary= 120000 |
| 192 | +``` |
| 193 | +
|
| 194 | +## 写入文件:fputc() |
| 195 | +
|
| 196 | +`fputc()` 函数用于将单个字符写入文件。它将一个字符输出到一个字符串 |
| 197 | +
|
| 198 | +```c |
| 199 | +int fputc(int c, FILE *stream) |
| 200 | +``` |
| 201 | +
|
| 202 | +```c |
| 203 | +#include <stdio.h> |
| 204 | +main(){ |
| 205 | + FILE *fp; |
| 206 | + fp = fopen("file1.txt", "w"); // 打开文件 |
| 207 | + fputc('a',fp); // 将单个字符写入文件 |
| 208 | + fclose(fp); // 关闭文件 |
| 209 | +} |
| 210 | +``` |
| 211 | +
|
| 212 | +## 读取文件:fgetc() |
| 213 | +
|
| 214 | +`fgetc()` 函数从文件中返回单个字符。它从流中获取一个字符。它在文件末尾返回 EOF: |
| 215 | +
|
| 216 | +```c |
| 217 | +int fgetc(FILE *stream) |
| 218 | +``` |
| 219 | +
|
| 220 | +```c |
| 221 | +#include<stdio.h> |
| 222 | +#include<conio.h> |
| 223 | +void main() { |
| 224 | + FILE *fp; |
| 225 | + char c; |
| 226 | + clrscr(); |
| 227 | + fp=fopen("myfile.txt", "r"); |
| 228 | + while((c=fgetc(fp))!=EOF){ |
| 229 | + printf("%c", c); |
| 230 | + } |
| 231 | + fclose(fp); |
| 232 | + getch(); |
| 233 | +} |
| 234 | +``` |
| 235 | +
|
| 236 | +## 写入文件:fputs() |
| 237 | +
|
| 238 | +`fputs()` 函数将一行字符写入文件。它将字符串输出到流 |
| 239 | +
|
| 240 | +```c |
| 241 | +int fputs(const char *s, FILE *stream) |
| 242 | +``` |
| 243 | +
|
| 244 | +```c |
| 245 | +#include<stdio.h> |
| 246 | +#include<conio.h> |
| 247 | +void main(){ |
| 248 | + FILE *fp; |
| 249 | + clrscr(); |
| 250 | + fp = fopen("myfile2.txt","w"); |
| 251 | + fputs("hello c programming",fp); |
| 252 | + fclose(fp); |
| 253 | + getch(); |
| 254 | +} |
| 255 | +``` |
| 256 | +
|
| 257 | +## 读取文件:fgets() |
| 258 | +
|
| 259 | +`fgets()` 函数从文件中读取一行字符。 它从流中获取字符串: |
| 260 | +
|
| 261 | +```c |
| 262 | +char* fgets(char *s, int n, FILE *stream) |
| 263 | +``` |
| 264 | +
|
| 265 | +```c |
| 266 | +#include<stdio.h> |
| 267 | +#include<conio.h> |
| 268 | +void main() { |
| 269 | + FILE *fp; |
| 270 | + char text[300]; |
| 271 | + clrscr(); |
| 272 | + |
| 273 | + fp=fopen("myfile2.txt", "r"); |
| 274 | + printf("%s", fgets(text, 200, fp)); |
| 275 | + fclose(fp); |
| 276 | + getch(); |
| 277 | +} |
| 278 | +``` |
| 279 | +
|
| 280 | +## fseek() |
| 281 | +
|
| 282 | +`fseek()` 函数用于将文件指针设置为指定的偏移量。 它用于将数据写入所需位置的文件: |
| 283 | +
|
| 284 | +```c |
| 285 | +int fseek(FILE *stream, long int offset, int whence) |
| 286 | +``` |
| 287 | +
|
| 288 | +`fseek()` 函数中使用了 3 个常量:`SEEK_SET`、`SEEK_CUR` 和 `SEEK_END`。 |
| 289 | +
|
| 290 | +```c |
| 291 | +#include <stdio.h> |
| 292 | +void main(){ |
| 293 | + FILE *fp; |
| 294 | + fp = fopen("myfile.txt","w+"); |
| 295 | + fputs("This is Book", fp); |
| 296 | + |
| 297 | + fseek(fp, 7, SEEK_SET); |
| 298 | + fputs("Kenny Wong", fp); |
| 299 | + fclose(fp); |
| 300 | +} |
| 301 | +``` |
| 302 | +
|
| 303 | +## rewind() |
| 304 | +
|
| 305 | +`rewind()` 函数将文件指针设置在流的开头。 如果您必须多次使用流,这很有用: |
| 306 | +
|
| 307 | +```c |
| 308 | +void rewind(FILE *stream) |
| 309 | +``` |
| 310 | +
|
| 311 | +```c |
| 312 | +#include<stdio.h> |
| 313 | +#include<conio.h> |
| 314 | +void main(){ |
| 315 | + FILE *fp; |
| 316 | + char c; |
| 317 | + clrscr(); |
| 318 | + fp=fopen("file.txt", "r"); |
| 319 | + while((c=fgetc(fp)) != EOF){ |
| 320 | + printf("%c", c); |
| 321 | + } |
| 322 | + rewind(fp); // 将文件指针移动到文件的开头 |
| 323 | + while((c=fgetc(fp)) != EOF){ |
| 324 | + printf("%c", c); |
| 325 | + } |
| 326 | + fclose(fp); |
| 327 | + getch(); |
| 328 | +} |
| 329 | +// 输出 |
| 330 | +// Hello World!Hello World! |
| 331 | +``` |
| 332 | +
|
| 333 | +如您所见,`rewind()` 函数将文件指针移动到文件的开头,这就是 `Hello World!` 被打印 2 次的原因。 如果你不调用 `rewind()` 函数,“Hello World!” 将只打印一次。 |
| 334 | +
|
| 335 | +## ftell() |
| 336 | +
|
| 337 | +`ftell()` 函数返回指定流的当前文件位置。 我们可以使用 `ftell()` 函数在文件末尾移动文件指针后获取文件的总大小。 我们可以使用 `SEEK_END` 常量将文件指针移动到文件末尾。 |
| 338 | +
|
| 339 | +```c |
| 340 | +long int ftell(FILE *stream) |
| 341 | +``` |
| 342 | + |
| 343 | +```c |
| 344 | +#include <stdio.h> |
| 345 | +#include <conio.h> |
| 346 | +void main (){ |
| 347 | + FILE *fp; |
| 348 | + int length; |
| 349 | + clrscr(); |
| 350 | + fp = fopen("file.txt", "r"); |
| 351 | + fseek(fp, 0, SEEK_END); |
| 352 | +
|
| 353 | + length = ftell(fp); |
| 354 | +
|
| 355 | + fclose(fp); |
| 356 | + printf("Size of file: %d bytes", length); |
| 357 | + getch(); |
| 358 | +} |
| 359 | +// 输出 |
| 360 | +// Size of file: 18 bytes |
| 361 | +``` |
0 commit comments