របៀបសរសេរឯកសារបញ្ចូលទៅ s. កំពុងបើកឯកសារ

ស្លាក: ឯកសារអត្ថបទ, fopen, fclose, feof, setbuf, setvbuf, fflush, fgetc, fprintf, fscanf, fgets, buffed stream, unbuffered stream។

ធ្វើការជាមួយឯកសារអត្ថបទ

ការធ្វើការជាមួយឯកសារអត្ថបទគឺស្រដៀងនឹងការធ្វើការជាមួយកុងសូល៖ ដោយប្រើមុខងារបញ្ចូលដែលបានធ្វើទ្រង់ទ្រាយ យើងរក្សាទុកទិន្នន័យទៅក្នុងឯកសារ ដោយប្រើមុខងារលទ្ធផលដែលបានធ្វើទ្រង់ទ្រាយ យើងអានទិន្នន័យពីឯកសារមួយ។ មាន nuances ជាច្រើនដែលយើងនឹងមើលនៅពេលក្រោយ។ ប្រតិបត្តិការសំខាន់ៗដែលត្រូវធ្វើគឺ

  • 1. បើកឯកសារដើម្បីឱ្យវាអាចចូលបាន។ ដូច្នោះហើយ អ្នកអាចបើកវាសម្រាប់អាន សរសេរ អាន និងសរសេរឡើងវិញ ឬសរសេរទៅចុងបញ្ចប់នៃឯកសារ។ល។ នៅពេលអ្នកបើកឯកសារ កំហុសជាច្រើនក៏អាចកើតឡើងផងដែរ - ឯកសារប្រហែលជាមិនមានទេ វាអាចជាប្រភេទឯកសារខុស អ្នកប្រហែលជាមិនមានការអនុញ្ញាតឱ្យធ្វើការជាមួយឯកសារ។ល។ ទាំងអស់នេះត្រូវតែយកទៅក្នុងគណនី។
  • 2. ធ្វើការដោយផ្ទាល់ជាមួយឯកសារ - ការសរសេរនិងការអាន។ នៅទីនេះយើងក៏ត្រូវចងចាំផងដែរថាយើងមិនដំណើរការជាមួយអង្គចងចាំចូលប្រើដោយចៃដន្យទេ ប៉ុន្តែជាមួយនឹងស្ទ្រីមដែលជាប់គាំង ដែលបន្ថែមភាពជាក់លាក់របស់វាផ្ទាល់។
  • 3. បិទឯកសារ។ ដោយសារឯកសារគឺជាធនធានខាងក្រៅរបស់កម្មវិធី ប្រសិនបើវាមិនត្រូវបានបិទ វានឹងបន្តព្យួរក្នុងអង្គចងចាំ សូម្បីតែបន្ទាប់ពីកម្មវិធីត្រូវបានបិទក៏ដោយ (ឧទាហរណ៍ វានឹងមិនអាចលុបឯកសារបើក ឬធ្វើការផ្លាស់ប្តូរបានទេ)។ ល។ ) លើសពីនេះទៀត ពេលខ្លះមិនចាំបាច់បិទ ប៉ុន្តែត្រូវ "បើកឡើងវិញ" ឯកសារតាមលំដាប់លំដោយ ឧទាហរណ៍ ដើម្បីប្តូររបៀបចូលប្រើ។

លើសពីនេះ មានកិច្ចការមួយចំនួនទៀត នៅពេលដែលយើងមិនចាំបាច់ចូលប្រើខ្លឹមសារនៃឯកសារ៖ ប្តូរឈ្មោះ ផ្លាស់ទី ចម្លង។ល។ ជាអកុសល ស្តង់ដារ C មិនមានការពិពណ៌នាអំពីមុខងារសម្រាប់តម្រូវការទាំងនេះទេ។ ជាការពិតណាស់ ពួកវាមានសម្រាប់ការអនុវត្តកម្មវិធីចងក្រងនីមួយៗ។ ការអានមាតិកានៃថតឯកសារ (ថត, ថត) ក៏កំពុងចូលប្រើឯកសារមួយដែរ ពីព្រោះថតឯកសារខ្លួនវាជាឯកសារដែលមានទ្រង់ទ្រាយមេតា។

ពេលខ្លះចាំបាច់ត្រូវអនុវត្តប្រតិបត្តិការជំនួយមួយចំនួន៖ ផ្លាស់ទីទៅទីតាំងដែលចង់បានក្នុងឯកសារ ចងចាំទីតាំងបច្ចុប្បន្ន កំណត់ប្រវែងឯកសារ។ល។

ដើម្បីធ្វើការជាមួយឯកសារ អ្នកត្រូវការវត្ថុ FILE ។ វត្ថុនេះរក្សាទុកឧបករណ៍កំណត់អត្តសញ្ញាណរបស់ស្ទ្រីមឯកសារ និងព័ត៌មានដែលត្រូវការដើម្បីគ្រប់គ្រងវា រួមទាំងទ្រនិចទៅសតិបណ្ដោះអាសន្នរបស់វា សូចនាករទីតាំងឯកសារ និងសូចនាករស្ថានភាព។

វត្ថុ FILE គឺជារចនាសម្ព័ន្ធដោយខ្លួនឯង ប៉ុន្តែវាលរបស់វាមិនគួរត្រូវបានចូលប្រើទេ។ កម្មវិធីចល័តត្រូវតែចាត់ទុកឯកសារជាវត្ថុអរូបីដែលអនុញ្ញាតឱ្យចូលប្រើការស្ទ្រីមឯកសារ។

ការបង្កើត និងការបែងចែកអង្គចងចាំសម្រាប់វត្ថុនៃប្រភេទ FILE ត្រូវបានអនុវត្តដោយប្រើមុខងារ fopen ឬ tmpfile (មានផ្សេងទៀត ប៉ុន្តែយើងនឹងផ្តោតលើចំណុចទាំងនេះប៉ុណ្ណោះ)។

មុខងារ fopen បើកឯកសារ។ វាទទួលបានអាគុយម៉ង់ពីរ - ខ្សែអក្សរដែលមានអាសយដ្ឋានឯកសារ និងខ្សែអក្សរដែលមានរបៀបចូលប្រើឯកសារ។ ឈ្មោះឯកសារអាចជាដាច់ខាត ឬទាក់ទង។ fopen ត្រឡប់ទ្រនិចទៅវត្ថុ FILE ដែលអាចត្រូវបានប្រើដើម្បីចូលប្រើឯកសារបន្ថែម។

ឯកសារ * fopen (ឈ្មោះឯកសារ const char * របៀប const char *);

ជាឧទាហរណ៍ សូមបើកឯកសារមួយ ហើយសរសេរ Hello World ទៅក្នុងវា។

# រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល void main() ( // ដោយប្រើអថេរឯកសារ យើងនឹងចូលប្រើឯកសារ FILE *file; // បើកឯកសារអត្ថបទជាមួយឯកសារអនុញ្ញាតការសរសេរ = fopen("C:/c/test.txt", "w+t") ; // សរសេរទៅឯកសារ fprintf (ឯកសារ "ជំរាបសួរពិភពលោក!" // បិទឯកសារ fclose (ឯកសារ);

មុខងារ fopen ខ្លួនវាបែងចែកអង្គចងចាំសម្រាប់ការសម្អាតវត្ថុត្រូវបានអនុវត្តដោយមុខងារ fclose ។ វាចាំបាច់ក្នុងការបិទឯកសារ; វានឹងមិនបិទដោយខ្លួនឯងទេ។

មុខងារ fopen អាច​បើក​ឯកសារ​ក្នុង​ទម្រង់​អត្ថបទ ឬ​ប្រព័ន្ធគោលពីរ។ លំនាំដើមគឺអត្ថបទ។ របៀបចូលប្រើអាចមានដូចខាងក្រោម

ជម្រើសចូលប្រើឯកសារ។
ប្រភេទ ការពិពណ៌នា
r ការអាន។ ឯកសារត្រូវតែមាន។
សរសេរឯកសារថ្មី។ ប្រសិនបើឯកសារដែលមានឈ្មោះដូចគ្នាមានរួចហើយ មាតិការបស់វានឹងត្រូវបាត់បង់។
សរសេរទៅចុងបញ្ចប់នៃឯកសារ។ ប្រតិបត្តិការកំណត់ទីតាំង (fseek, fsetpos, frewind) មិនត្រូវបានអើពើ។ ឯកសារត្រូវបានបង្កើតប្រសិនបើវាមិនមាន។
r+ ការអាននិងការធ្វើបច្ចុប្បន្នភាព។ អ្នកអាចអាននិងសរសេរបាន។ ឯកសារត្រូវតែមាន។
w+ ការថតនិងធ្វើបច្ចុប្បន្នភាព។ ឯកសារថ្មីមួយត្រូវបានបង្កើត។ ប្រសិនបើឯកសារដែលមានឈ្មោះដូចគ្នាមានរួចហើយ មាតិការបស់វានឹងត្រូវបាត់បង់។ អ្នកអាចទាំងសរសេរ និងអាន។
ក+ បញ្ចប់ការបង្ហោះ និងធ្វើបច្ចុប្បន្នភាព។ ប្រតិបត្តិការកំណត់ទីតាំងគឺបានតែអានហើយមិនអើពើសម្រាប់ការសរសេរ។ ប្រសិនបើឯកសារមិនមានទេ ឯកសារថ្មីមួយនឹងត្រូវបានបង្កើត។

ប្រសិនបើចាំបាច់ត្រូវបើកឯកសារក្នុងរបៀបគោលពីរ នោះអក្សរ b ត្រូវបានបន្ថែមទៅចុងបន្ទាត់ ឧទាហរណ៍ “rb”, “wb”, “ab” ឬសម្រាប់របៀបចម្រុះ “ab+”, “ wb+”, “ab+”។ ជំនួសឱ្យ b អ្នកអាចបន្ថែមអក្សរ t បន្ទាប់មកឯកសារនឹងបើកក្នុងរបៀបអត្ថបទ។ វាអាស្រ័យលើការអនុវត្ត។ នៅក្នុងស្តង់ដារ C ថ្មី (2011) អក្សរ x មានន័យថា fopen គួរតែបរាជ័យប្រសិនបើឯកសារមានរួចហើយ។ ចូរបំពេញបន្ថែមកម្មវិធីចាស់របស់យើង៖ បើកឯកសារឡើងវិញ ហើយពិចារណាពីអ្វីដែលយើងបានសរសេរនៅទីនោះ។

# រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល void main() ( FILE *file; char buffer; file = fopen("C:/c/test.txt", "w"); fprintf(file, "Hello, World!"); fclose(file); file = fopen("C:/c/test.txt", "r"); fgets(buffer, 127, file);

ជំនួសឱ្យមុខងារ fgets អ្នកអាចប្រើ fscanf ប៉ុន្តែអ្នកត្រូវចាំថាវាអាចអានបានត្រឹមតែចន្លោះដំបូងប៉ុណ្ណោះ។
fscanf(ឯកសារ, "%127s", សតិបណ្ដោះអាសន្ន);

ដូចគ្នានេះផងដែរជំនួសឱ្យការបើកនិងបិទឯកសារអ្នកអាចប្រើមុខងារ freopen ដែល "បើកឡើងវិញ" ឯកសារជាមួយនឹងសិទ្ធិចូលប្រើថ្មី។

# រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល void main() ( FILE *file; char buffer; file = fopen("C:/c/test.txt", "w"); fprintf(file, "Hello, World!"); freopen("C:/ c/test.txt", "r", file); fgets(buffer, 127, file); printf("%s", buffer); fclose(file); getch(); )

មុខងារ fprintf និង fscanf ខុសពី printf និង scanf តែនៅក្នុងនោះពួកគេយកជាអាគុយម៉ង់ដំបូងរបស់ពួកគេនូវទ្រនិចទៅឯកសារដែលពួកគេនឹងបញ្ចេញ ឬពីអ្វីដែលពួកគេនឹងអានទិន្នន័យ។ វាមានតម្លៃបន្ថែមភ្លាមៗថាមុខងារ printf និង scanf អាចត្រូវបានជំនួសយ៉ាងងាយស្រួលដោយមុខងារ fprintf និង fscanf ។ នៅក្នុងប្រព័ន្ធប្រតិបត្តិការ (យើងកំពុងពិចារណាលើប្រព័ន្ធប្រតិបត្តិការធម្មតាបំផុត និងគ្រប់គ្រាន់) មានស្ទ្រីមស្តង់ដារចំនួនបី៖ ស្ទ្រីមទិន្នផលស្តង់ដារ stdout ស្ទ្រីមបញ្ចូលស្តង់ដារ stdin និងស្ទ្រីមលទ្ធផលកំហុសស្តង់ដារ stderr ។ ពួកវាត្រូវបានបើកដោយស្វ័យប្រវត្តិនៅពេលដែលកម្មវិធីត្រូវបានបើកដំណើរការ ហើយត្រូវបានភ្ជាប់ជាមួយកុងសូល។ ឧទាហរណ៍

# រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល void main() ( int a, b; fprintf(stdout, "បញ្ចូលលេខពីរ\n"); fscanf(stdin, "%d", &a); fscanf(stdin, "%d", &b); ប្រសិនបើ (b == 0) ( fprintf(stderr, "កំហុស៖ ចែកដោយសូន្យ"); ) else ( fprintf(stdout, "%3f", (float) a / (float) b); ) getch();

កំហុសក្នុងការបើកឯកសារ

ប្រសិនបើការហៅមុខងារ fopen បរាជ័យ វានឹងត្រឡប់ NULL វិញ។ កំហុសនៅពេលធ្វើការជាមួយឯកសារកើតឡើងជាញឹកញាប់ ដូច្នេះរាល់ពេលដែលយើងបើកឯកសារ យើងត្រូវពិនិត្យមើលលទ្ធផលការងារ

# រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល #define ERROR_OPEN_FILE -3 void main() ( FILE *file; char buffer; file = fopen("C:/c/test.txt", "w"); if (file == NULL) ( printf("កំហុសក្នុងការបើក ឯកសារ"); getch(); ចេញ(ERROR_OPEN_FILE); ) fprintf(ឯកសារ "ជំរាបសួរពិភពលោក!"); freopen("C:/c/test.txt", "r", ឯកសារ); ប្រសិនបើ (ឯកសារ = = NULL) ( printf("កំហុសក្នុងការបើកឯកសារ"); getch(); exit(ERROR_OPEN_FILE); ) fgets(buffer, 127, file) printf("%s", buffer(file); )

បញ្ហាកើតឡើងនៅពេលដែលឯកសារជាច្រើនត្រូវបានបើកក្នុងពេលតែមួយ៖ ប្រសិនបើមួយក្នុងចំណោមពួកវាមិនអាចបើកបានទេនោះឯកសារដែលនៅសល់ក៏ត្រូវបិទផងដែរ។

ឯកសារ *inputFile, *outputFile;

មិនបានចុះហត្ថលេខា m, n;

មិនបានចុះហត្ថលេខា i, j;

inputFile = fopen(INPUT_FILE, READ_ONLY);

  • ប្រសិនបើ (inputFile == NULL) ( printf("កំហុសក្នុងការបើកឯកសារ %s", INPUT_FILE); getch(); exit(3); ) outputFile = fopen(OUTPUT_FILE, WRITE_ONLY);
  • if (outputFile == NULL) ( printf("កំហុសក្នុងការបើកឯកសារ %s", OUTPUT_FILE); getch(); if (inputFile != NULL) ( fclose(inputFile); ) exit(4); ) ...
  • ក្នុង​ករណី​សាមញ្ញ អ្នក​អាច​ធ្វើ​ជា​ប្រធាន​ដូច​នៅ​ក្នុង​លេខ​កូដ​មុន​។ ក្នុងករណីដែលស្មុគ្រស្មាញជាងនេះ វិធីសាស្ត្រត្រូវបានប្រើដែលជំនួស RAII ពី C ++: wrappers ឬ compiler features (cleanup in GCC) ជាដើម។
  • ការផ្ទុកទិន្នន័យ

ដូចដែលបានរៀបរាប់ខាងលើ នៅពេលដែលយើងបញ្ចេញទិន្នន័យ វាត្រូវបានដាក់ដំបូងនៅក្នុងសតិបណ្ដោះអាសន្ន។ សតិបណ្ដោះអាសន្នត្រូវបានសម្អាត

# រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល 1) ប្រសិនបើវាពេញ

2) ប្រសិនបើស្ទ្រីមត្រូវបានបិទ

3) ប្រសិនបើយើងបង្ហាញយ៉ាងច្បាស់ថាវាចាំបាច់ដើម្បីជម្រះសតិបណ្ដោះអាសន្ន (មានករណីលើកលែងនៅទីនេះផងដែរ :)) ។

4) ជម្រះផងដែរប្រសិនបើកម្មវិធីបានបញ្ចប់ដោយជោគជ័យ។ ក្នុងពេលជាមួយគ្នានោះឯកសារទាំងអស់ត្រូវបានបិទ។ ក្នុងករណីមានកំហុសពេលរត់ វាប្រហែលជាមិនកើតឡើងទេ។

អ្នក​អាច​បង្ខំ​មិន​ផ្ទុក​សតិបណ្ដោះអាសន្ន​ដោយ​ហៅ​មុខងារ fflush(File *)។ សូមក្រឡេកមើលឧទាហរណ៍ពីរ - ដោយមាននិងគ្មានការសម្អាត។

void main() ( FILE *file; char c; file = fopen("C:/c/test.txt", "w"); do ( c = getch(); fprintf(file, "%c", c ); fprintf(stdout, "%c", c //fflush(ឯកសារ);

មិនបញ្ចេញមតិលើការហៅចេញ។ នៅពេលដំណើរការ សូមបើកឯកសារអត្ថបទ ហើយមើលឥរិយាបថ។

  • អ្នកអាចកំណត់បណ្តុំឯកសារដោយខ្លួនឯងដោយកំណត់ទំហំផ្ទាល់ខ្លួនរបស់អ្នក។ នេះត្រូវបានធ្វើដោយប្រើមុខងារ Setbuf (ឯកសារ * ស្ទ្រីម, char * buffer);
  • ដែលយកឯកសារដែលបានបើករួចហើយ និងទ្រនិចទៅសតិបណ្ដោះអាសន្នថ្មី។ ទំហំនៃបណ្តុំថ្មីត្រូវតែមិនតិចជាង BUFSIZ (ឧទាហរណ៍នៅលើស្ថានីយការងារបច្ចុប្បន្ន BUFSIZ គឺ 512 បៃ)។ ប្រសិនបើអ្នកឆ្លងកាត់ NULL ជាបណ្ដោះអាសន្ន នោះស្ទ្រីមនឹងមិនមានសតិបណ្ដោះអាសន្នទេ។ អ្នកក៏អាចប្រើមុខងារបានដែរ។ Int setvbuf(FILE * stream, char * buffer, int mode, size_t size);
  • ដែលទទួលយកបណ្តុំនៃទំហំទំហំបំពាន។ របៀបអាចយកតម្លៃដូចខាងក្រោម- គ្មានការផ្អាក។ ក្នុងករណីនេះ ទំហំ និងប៉ារ៉ាម៉ែត្រសតិបណ្ដោះអាសន្នមិនត្រូវបានអើពើ។
ប្រសិនបើជោគជ័យ មុខងារនឹងត្រឡប់ 0 ។

ឧទាហរណ៍៖ ចូរយើងកំណត់សតិបណ្ដោះអាសន្នរបស់យើង ហើយមើលពីរបៀបដែលការអានឯកសារត្រូវបានអនុវត្ត។ សូមឱ្យឯកសារខ្លី (អ្វីមួយដូចជា Hello, World!) ហើយយើងអានវាតាមតួអក្សរ

# រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល void main() ( FILE *input = NULL; char c; char buffer = (0); input = fopen("D:/c/text.txt", "rt"); setbuf(input, buffer); while ( !feof(បញ្ចូល)) ( c = fgetc(បញ្ចូល); printf("%c\n", c); printf("%s\n", buffer); _getch(); ) fclose(បញ្ចូល)

វាអាចត្រូវបានគេមើលឃើញថាទិន្នន័យមានរួចហើយនៅក្នុងសតិបណ្ដោះអាសន្ន។ ការអានតួអក្សរតាមតួអក្សរត្រូវបានធ្វើពីសតិបណ្ដោះអាសន្ន។

feof

មុខងារ int feof (ឯកសារ * ស្ទ្រីម); ត្រឡប់ពិតប្រសិនបើចុងបញ្ចប់នៃឯកសារត្រូវបានឈានដល់។ មុខងារនេះងាយស្រួលប្រើនៅពេលដែលអ្នកត្រូវឆ្លងកាត់ឯកសារទាំងមូលពីដើមដល់ចប់។ សូមឱ្យមានឯកសារដែលមានមាតិកាអត្ថបទ text.txt ។ យើងអានឯកសារតាមតួអក្សរ ហើយបង្ហាញវានៅលើអេក្រង់។

# រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល void main() ( FILE *input = NULL; char c; input = fopen("D:/c/text.txt", "rt"); ប្រសិនបើ (បញ្ចូល == NULL) ( printf("កំហុសក្នុងការបើកឯកសារ") ; _getch(); ចេញ(0); ខណៈពេល (!feof(បញ្ចូល)) (c = fgetc(បញ្ចូល); fprintf(stdout, "%c", c); ) fclose(បញ្ចូល());

អ្វីគ្រប់យ៉ាងនឹងល្អ ប៉ុន្តែមុខងារ feof មិនដំណើរការត្រឹមត្រូវ... នេះគឺដោយសារតែការពិតដែលថាគំនិតនៃ "ចុងបញ្ចប់នៃឯកសារ" មិនត្រូវបានកំណត់។ កំហុសដែលជារឿយៗកើតឡើងនៅពេលប្រើ feof គឺថាទិន្នន័យចុងក្រោយដែលបានអានត្រូវបានបោះពុម្ពពីរដង។ នេះគឺដោយសារតែការពិតដែលថាទិន្នន័យត្រូវបានសរសេរទៅសតិបណ្ដោះអាសន្នបញ្ចូល ការអានចុងក្រោយកើតឡើងដោយមានកំហុស ហើយមុខងារត្រឡប់តម្លៃចាស់ដែលបានអាន។

# រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល void main() ( FILE *input = NULL; char c; input = fopen("D:/c/text.txt", "rt"); ប្រសិនបើ (បញ្ចូល == NULL) ( printf("កំហុសក្នុងការបើកឯកសារ") ; _getch(); ចេញ(0); ខណៈពេល (!feof(បញ្ចូល)) (fscanf(បញ្ចូល, "%c", &c); fprintf(stdout, "%c", c); ) fclose(បញ្ចូល); ();

ឧទាហរណ៍នេះនឹងបរាជ័យ (ភាគច្រើនទំនងជា) ហើយបោះពុម្ពតួអក្សរចុងក្រោយនៃឯកសារពីរដង។

ដំណោះស្រាយគឺមិនត្រូវប្រើ feof ទេ។ ឧទាហរណ៍ រក្សាទុកចំនួនសរុបនៃកំណត់ត្រា ឬប្រើការពិតដែលថាមុខងារ fscanf ។ល។ ជាធម្មតាត្រឡប់ចំនួនតម្លៃដែលបានអាន និងត្រូវគ្នាយ៉ាងត្រឹមត្រូវ។

# រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល void main() ( FILE *input = NULL; char c; input = fopen("D:/c/text.txt", "rt"); ប្រសិនបើ (បញ្ចូល == NULL) ( printf("កំហុសក្នុងការបើកឯកសារ") ; _getch(); ចេញ(0); ខណៈពេល (fscanf(បញ្ចូល, "%c", &c) == 1) ( fprintf(stdout, "%c", c);

ឧទាហរណ៍

1. ឯកសារមួយមានលេខពីរ - វិមាត្រនៃអារេ។ ចូរបំពេញឯកសារទីពីរដោយអារេនៃលេខចៃដន្យ។

# រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល // ឈ្មោះឯកសារ និងការអនុញ្ញាត #define INPUT_FILE "D:/c/input.txt" #define OUTPUT_FILE "D:/c/output.txt" #define READ_ONLY "r" #define WRITE_ONLY "w" // តម្លៃអតិបរមាសម្រាប់អារេ ទំហំ #define MAX_DIMENSION 100 // កំហុសពេលបើកឯកសារ #define ERROR_OPEN_FILE -3 void main() ( FILE *inputFile, *outputFile; unsigned m, n; unsigned i, j; inputFile = fopen(INPUT_FILE, READ_ONLY); ប្រសិនបើ ( inputFile == NULL) ( printf("កំហុសក្នុងការបើកឯកសារ %s", INPUT_FILE); getch(); exit(ERROR_OPEN_FILE); ) outputFile = fopen(OUTPUT_FILE, WRITE_ONLY) ប្រសិនបើ (outputFile == NULL) (printf("កំហុស ការបើកឯកសារ %s", OUTPUT_FILE); getch(); // ប្រសិនបើឯកសារអាចត្រូវបានបើកសម្រាប់ការអាន នោះវាត្រូវតែបិទប្រសិនបើ (inputFile != NULL) ( fclose(inputFile); ) ចេញ (ERROR_OPEN_FILE); ) fscanf (inputFile, "%ud %ud", &m, &n); ប្រសិនបើ (m > MAX_DIMENSION) ( m = MAX_DIMENSION; ) if (n > MAX_DIMENSION) ( n = MAX_DIMENSION; ) srand(time(NULL));< n; i++) { for (j = 0; j < m; j++) { fprintf(outputFile, "%8d ", rand()); } fprintf(outputFile, "\n"); } //Закрываем файлы fclose(inputFile); fclose(outputFile); }

2. អ្នកប្រើប្រាស់ចម្លងឯកសារ ហើយជ្រើសរើសរបៀបប្រតិបត្តិការជាមុនសិន៖ ឯកសារអាចត្រូវបានបញ្ចេញទៅកុងសូល ឬចម្លងទៅឯកសារថ្មី។

# រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល #កំណត់ ERROR_FILE_OPEN -3 void main() ( FILE *origin = NULL; FILE *output = NULL; char filename; int mode; printf("Enter filename:"); scanf("%1023s", filename); origin = fopen (ឈ្មោះឯកសារ "r"); ប្រសិនបើ (ប្រភពដើម == NULL) ( printf("កំហុសក្នុងការបើកឯកសារ %s", ឈ្មោះឯកសារ); getch(); ចេញ(ERROR_FILE_OPEN); ) printf("បញ្ចូលរបៀប៖ "" % d", &mode); ប្រសិនបើ (របៀប == 1) ( printf("បញ្ចូលឈ្មោះឯកសារ៖ "); scanf("%1023s", ឈ្មោះឯកសារ); លទ្ធផល = fopen(ឈ្មោះឯកសារ, "w"); ប្រសិនបើ (លទ្ធផល = = NULL ) ( printf("កំហុសក្នុងការបើកឯកសារ %s", ឈ្មោះឯកសារ); getch(); fclose(ប្រភពដើម); ចេញ(ERROR_FILE_OPEN); ) ) else ( output = stdout; ) ខណៈពេលដែល (!feof(origin)) (fprintf (លទ្ធផល , "%c", fgetc(ប្រភពដើម));

3. អ្នកប្រើប្រាស់បញ្ចូលទិន្នន័យពីកុងសូល ហើយវាត្រូវបានសរសេរទៅឯកសារមួយរហូតដល់គ្រាប់ចុច esc ត្រូវបានចុច។ ពិនិត្យមើលកម្មវិធីហើយមើល។ របៀបដែលវាមានឥរិយាបទប្រសិនបើអ្នកបញ្ចូល backspace: អ្វីដែលជាលទ្ធផលទៅឯកសារ និងអ្វីដែលជាលទ្ធផលទៅកុងសូល។

# រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល #define ERROR_FILE_OPEN -3 void main() ( FILE *output = NULL; char c; output = fopen("D:/c/test_output.txt", "w+t"); ប្រសិនបើ (លទ្ធផល == NULL) (printf ("កំហុសក្នុងការបើកឯកសារ"); _getch(); ចេញ(ERROR_FILE_OPEN); , stdout);

4. ឯកសារមានចំនួនគត់។ ស្វែងរកអតិបរមានៃពួកគេ។ ចូរយើងទាញយកប្រយោជន៍ពីការពិតដែលថាមុខងារ fscanf ត្រឡប់ចំនួននៃវត្ថុដែលបានអាន និងផ្គូផ្គងត្រឹមត្រូវ។ លេខ 1 គួរតែត្រលប់មកវិញរាល់ពេល។

# រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល #define ERROR_FILE_OPEN -3 void main() ( FILE *input = NULL; int num, maxn, hasRead; input = fopen("D:/c/input.txt", "r"); ប្រសិនបើ (បញ្ចូល == NULL) ( printf("កំហុសក្នុងការបើកឯកសារ"); _getch(); exit(ERROR_FILE_OPEN); ) maxn = INT_MIN; hasRead = 1; if (hasRead != 1) ( បន្ត ; ) if (num >

ដំណោះ​ស្រាយ​មួយ​ទៀត​គឺ​ត្រូវ​អាន​លេខ​រហូត​ដល់​ចប់​ឯកសារ។

# រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល #define ERROR_FILE_OPEN -3 void main() ( FILE *input = NULL; int num, maxn, hasRead; input = fopen("D:/c/input.txt", "r"); ប្រសិនបើ (បញ្ចូល == NULL) ( printf("កំហុសក្នុងការបើកឯកសារ"); _getch(); exit(ERROR_FILE_OPEN); ) maxn = INT_MIN; while (!feof(input)) (fscanf(input, "%d", &num); if (num > maxn ) ( maxn = num; ) ) printf("ចំនួនអតិបរមា = %d", maxn);

5. ឯកសារមានពាក្យ៖ ពាក្យរុស្ស៊ី តារាងពាក្យ អង់គ្លេស ក្នុងជួរជាច្រើន។ អ្នក​ប្រើ​បញ្ចូល​ពាក្យ​ជា​ភាសា​អង់គ្លេស​, វា​ជា​ការ​ចាំបាច់​ដើម្បី​ចេញ​ជា​ភាសា​រុស្ស៊ី​។

ឯកសារបកប្រែមើលទៅដូចនេះ

ព្រះអាទិត្យព្រះអាទិត្យ
ខ្មៅដៃ
ខ្មៅដៃប៊ិចប៊ិច
ទ្វារទ្វារ
បង្អួចបង្អួច
កៅអីកៅអី
កៅអី

និងរក្សាទុកនៅក្នុងការអ៊ិនកូដ cp866 (OEM 866) ។ វាសំខាន់ណាស់៖ ពាក្យគូចុងក្រោយក៏បញ្ចប់ដោយបន្ទាត់។

ក្បួនដោះស្រាយមានដូចខាងក្រោម៖ យើងអានបន្ទាត់ពីឯកសារ ស្វែងរកស្លាកសញ្ញាក្នុងបន្ទាត់ ជំនួសស្លាកសញ្ញាដោយលេខសូន្យ ចម្លងពាក្យរុស្ស៊ីពីសតិបណ្ដោះអាសន្ន ចម្លងពាក្យអង់គ្លេសពីសតិបណ្ដោះអាសន្ន ពិនិត្យមើលសមភាព។

# រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល #define ERROR_FILE_OPEN -3 void main() ( FILE *input = NULL; char buffer; char enWord; char ruWord; char usrWord; unsigned index; int length; int wasFound; input = fopen("D:/c/input.txt ", "r"); ប្រសិនបើ (បញ្ចូល == NULL) ( printf("កំហុសក្នុងការបើកឯកសារ"); _getch(); exit(ERROR_FILE_OPEN); ) printf("បញ្ចូលពាក្យ៖ "); fgets(usrWord, 127, stdin ); wasFound = 0; while (!feof(បញ្ចូល)) ( fgets(buffer, 511, input); length = strlen(buffer); សម្រាប់ (index = 0; index< length; index++) { if (buffer == "\t") { buffer = "\0"; break; } } strcpy(ruWord, buffer); strcpy(enWord, &buffer); if (!strcmp(enWord, usrWord)) { wasFound = 1; break; } } if (wasFound) { printf("%s", ruWord); } else { printf("Word not found"); } fclose(input); _getch(); }

6. រាប់ចំនួនបន្ទាត់ក្នុងឯកសារ។ យើងនឹងអានតួអក្សរឯកសារតាមតួអក្សរ ដោយរាប់ចំនួនតួអក្សរ "\n" រហូតដល់យើងជួបតួអក្សរ EOF ។ EOF គឺជាតួអក្សរពិសេសដែលបង្ហាញថាការបញ្ចូលបានបញ្ចប់ ហើយមិនមានទិន្នន័យដែលត្រូវអានទៀតទេ។ អនុគមន៍ត្រឡប់តម្លៃអវិជ្ជមានក្នុងករណីមានកំហុស។
ចំណាំ៖ EOF គឺជាប្រភេទ int ដូច្នេះអ្នកត្រូវប្រើ int ដើម្បីអានតួអក្សរ។ លើសពីនេះទៀតតម្លៃនៃ EOF មិនត្រូវបានកំណត់ដោយស្តង់ដារទេ។

#កំណត់ _CRT_SECURE_NO_WARNINGS #រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល int cntLines(const char *filename) ( int lines = 0; int any; // ណាមួយគឺជាប្រភេទ int ព្រោះ EOF គឺជាប្រភេទ int! FILE *f = fopen(filename, "r"); ប្រសិនបើ (f == NULL ) (ត្រឡប់ -1; ) ធ្វើ (ណាមួយ = fgetc(f); //printf("%c", ណាមួយ);// បំបាត់កំហុសប្រសិនបើ (ណាមួយ == "\n") (បន្ទាត់ ++; ) ) ខណៈពេលដែល (ណាមួយ ! =EOF ​​fclose(f);

Ru-Cyrl 18- ការបង្រៀន Sypachev S.S. ១៩៨៩-០៤-១៤[អ៊ីមែលការពារ]លោក Stepan Sypachev

សិស្ស

នៅតែមិនច្បាស់? - សរសេរសំណួរទៅប្រអប់សំបុត្រ

ពីមុននៅពេលបញ្ចូល និងបញ្ចេញទិន្នន័យ យើងធ្វើការជាមួយស្ទ្រីមស្តង់ដារ - ក្តារចុច និងម៉ូនីទ័រ។ ឥឡូវនេះសូមមើលពីរបៀបដែលភាសា C អនុវត្តការទទួលទិន្នន័យពីឯកសារ ហើយសរសេរវានៅទីនោះ។ មុនពេលអ្នកអាចអនុវត្តប្រតិបត្តិការទាំងនេះ អ្នកត្រូវតែបើកឯកសារ ហើយចូលប្រើវា។
នៅក្នុងភាសាសរសេរកម្មវិធី C ទ្រនិចទៅឯកសារគឺប្រភេទ FILE ហើយការប្រកាសរបស់វាមើលទៅដូចនេះ៖

ឯកសារ * myfile;
ម្យ៉ាងវិញទៀត មុខងារ fopen() បើកឯកសារនៅអាសយដ្ឋានដែលបានបញ្ជាក់ជាអាគុយម៉ង់ដំបូងក្នុងរបៀបអាន ("r") របៀបសរសេរ ("w") ឬរបៀបបន្ថែម ("a") ហើយត្រឡប់ទ្រនិច ទៅវាទៅកម្មវិធី។ ដូច្នេះដំណើរការនៃការបើកឯកសារនិងភ្ជាប់វាទៅកម្មវិធីមើលទៅដូចនេះ:

myfile = fopen("hello.txt", "r");

នៅពេលអាន ឬសរសេរទិន្នន័យទៅឯកសារ វាត្រូវបានចូលប្រើតាមរយៈទ្រនិចឯកសារ (ក្នុងករណីនេះ myfile)។

ប្រសិនបើសម្រាប់ហេតុផលមួយ ឬហេតុផលផ្សេងទៀត (មិនមានឯកសារនៅអាសយដ្ឋានដែលបានបញ្ជាក់ទេ ការចូលប្រើវាត្រូវបានបដិសេធ) មុខងារ fopen() មិនអាចបើកឯកសារបានទេ នោះវាត្រឡប់ NULL ។ នៅក្នុងកម្មវិធីពិត ពួកគេស្ទើរតែតែងតែដោះស្រាយកំហុសក្នុងការបើកឯកសារនៅក្នុងសាខា if ប៉ុន្តែយើងនឹងលុបវាបន្ថែមទៀត។

ការប្រកាសមុខងារ fopen() មាននៅក្នុងឯកសារបឋមកថា stdio.h ដូច្នេះវាត្រូវតែរួមបញ្ចូល។ ផងដែរនៅក្នុង stdio.h ប្រភេទរចនាសម្ព័ន្ធ FILE ត្រូវបានប្រកាស។
បន្ទាប់ពីធ្វើការជាមួយឯកសារត្រូវបានបញ្ចប់ វាជាទម្លាប់ក្នុងការបិទវាដើម្បីរំដោះសតិបណ្ដោះអាសន្នពីទិន្នន័យ និងសម្រាប់ហេតុផលផ្សេងទៀត។ នេះមានសារៈសំខាន់ជាពិសេសប្រសិនបើកម្មវិធីបន្តដំណើរការបន្ទាប់ពីធ្វើការជាមួយឯកសារ។ ការបំបែកការតភ្ជាប់រវាងឯកសារខាងក្រៅ និងទ្រនិចទៅវាពីកម្មវិធី ត្រូវបានធ្វើដោយប្រើមុខងារ fclose()។ ទ្រនិចទៅឯកសារត្រូវបានបញ្ជូនទៅវាជាប៉ារ៉ាម៉ែត្រ៖

ឯកសារច្រើនជាងមួយអាចត្រូវបានបើកនៅក្នុងកម្មវិធី។ ក្នុងករណីនេះ ឯកសារនីមួយៗត្រូវតែភ្ជាប់ជាមួយទ្រនិចឯកសាររបស់វា។ ទោះយ៉ាងណាក៏ដោយ ប្រសិនបើកម្មវិធីដំបូងដំណើរការជាមួយឯកសារមួយ ហើយបន្ទាប់មកបិទវា នោះទ្រនិចអាចត្រូវបានប្រើដើម្បីបើកឯកសារទីពីរ។

ការអានពី និងសរសេរទៅឯកសារអត្ថបទ

fscanf()

មុខងារ fscanf() មានអត្ថន័យស្រដៀងគ្នាទៅនឹងមុខងារ scanf() ប៉ុន្តែមិនដូចវាទេ វាផ្តល់នូវការបញ្ចូលដែលបានធ្វើទ្រង់ទ្រាយពីឯកសារជាជាងស្ទ្រីមបញ្ចូលស្តង់ដារ។ មុខងារ fscanf() យកប៉ារ៉ាម៉ែត្រ៖ ទ្រនិចឯកសារ ខ្សែទម្រង់ អាសយដ្ឋាននៃតំបន់សតិសម្រាប់សរសេរទិន្នន័យ៖
fscanf(myfile, "%s%d", str, &a);

ត្រឡប់ចំនួននៃទិន្នន័យដែលបានអានដោយជោគជ័យ ឬ EOF ។ ចន្លោះ និងតួអក្សរបន្ទាត់ថ្មីត្រូវបានរាប់ជាអ្នកកំណត់ទិន្នន័យ។

ឧបមាថាយើងមានឯកសារដែលមានការពិពណ៌នាដូចខាងក្រោមនៃវត្ថុ៖

ផ្លែប៉ោម 10 23.4 ចេក 5 25.0 នំបុ័ង 1 10.3

# រួមបញ្ចូល main () ( ឯកសារ * ឯកសារ ; រចនាសម្ព័ន្ធអាហារ ( ឈ្មោះតួអក្សរ [ 20 ] ; គ្មានចុះហត្ថលេខា qty; តម្លៃអណ្តែត; ); ហាងអាហាររចនាសម្ព័ន្ធ [ 10 ] ; char i= 0 ; ឯកសារ = fopen ( "fscanf.txt", "r" ); ខណៈ (fscanf (ឯកសារ "%s%u%f" ហាង[i].name , & (shop[i].qty ), & (shop[i].price) != EOF) ( printf ( "%s %u %2f \n", shop[i].name, shop[i].qty, shop[i].price);

ខ្ញុំ++;

))

ក្នុងករណីនេះរចនាសម្ព័ន្ធនិងអារេនៃរចនាសម្ព័ន្ធត្រូវបានប្រកាស។ បន្ទាត់នីមួយៗពីឯកសារត្រូវគ្នាទៅនឹងធាតុមួយនៃអារេ។ ធាតុអារេគឺជារចនាសម្ព័ន្ធដែលមានខ្សែអក្សរ និងវាលលេខពីរ។ រង្វិលជុំអានមួយជួរក្នុងមួយដង។ នៅពេលដែលចុងបញ្ចប់នៃឯកសារត្រូវបានជួបប្រទះ fscanf() ត្រឡប់ EOF ហើយរង្វិលជុំបញ្ចប់។
fgets()

មុខងារ fgets() គឺស្រដៀងទៅនឹងមុខងារ gets() ហើយអនុវត្តការបញ្ចូលតាមបន្ទាត់ពីឯកសារ។ ការហៅមួយទៅកាន់ fgets() នឹងអានមួយបន្ទាត់។ ក្នុងករណីនេះអ្នកមិនអាចអានបន្ទាត់ទាំងមូលបានទេប៉ុន្តែមានតែផ្នែកខ្លះរបស់វាពីដំបូងប៉ុណ្ណោះ។ ប៉ារ៉ាម៉ែត្រ fgets () មើលទៅដូចនេះ:
fgets (character_array, number_of_characters_read, pointer_to_file)

ឧទាហរណ៍៖

# រួមបញ្ចូល #define N 80 main () ( FILE * file; char arr[ N ] ; file = fopen ( "fscanf.txt" , "r" ); while (fgets (arr, N, file) != NULL) printf (" %s", arr); printf (" \n") ;

fclose (ឯកសារ);

)

នៅក្នុងកម្មវិធីនេះ មិនដូចកម្មវិធីមុនទេ ទិន្នន័យត្រូវបានអានតាមបន្ទាត់មួយៗទៅក្នុងអារេអារេ។ នៅពេលអានបន្ទាត់បន្ទាប់ លេខមុននឹងបាត់។ អនុគមន៍ fgets() ត្រឡប់ NULL ប្រសិនបើវាមិនអាចអានបន្ទាត់បន្ទាប់បានទេ។

getc() ឬ fgetc() \n"មុខងារ getc() ឬ fgetc() (ការងារទាំងពីរ) អនុញ្ញាតឱ្យអ្នកទទួលបានតួអក្សរតែមួយបន្ទាប់ពីឯកសារមួយ។ \0 " while ((arr[i] = fgetc (file)) != EOF) (ប្រសិនបើ (arr[i] == " \n") (arr[i] = " \0 " while ((arr[i] = fgetc (file)) != EOF) (ប្រសិនបើ (arr[i] == " \n";

printf("%s

, arr);

i = 0 ;

  • ផ្សេងទៀត i++;
  • )arr[i] = "
  • , arr);

កូដឧទាហរណ៍បង្ហាញទិន្នន័យពីឯកសារនៅលើអេក្រង់។

ការសរសេរទៅឯកសារអត្ថបទ

ដូច​នឹង​ការ​បញ្ចូល​ដែរ លទ្ធផល​ទៅ​ឯកសារ​អាច​ខុស​គ្នា។ \n"លទ្ធផលដែលបានធ្វើទ្រង់ទ្រាយ។ មុខងារ fprintf (file_index, format_string, variables) ។

លទ្ធផលបន្ទាប់បន្សំ។ មុខងារ fputs (ខ្សែអក្សរ, file_pointer) ។

លទ្ធផល​តួអក្សរ​ដោយ​តួអក្សរ។ មុខងារ fputc() ឬ putc(និមិត្តសញ្ញា file_pointer) ។ \n"ខាងក្រោម​នេះ​ជា​ឧទាហរណ៍​កូដ​ដែល​ប្រើ​វិធី​បី​យ៉ាង​ក្នុង​ការ​បញ្ចេញ​ទិន្នន័យ​ទៅ​ឯកសារ។

ការសរសេរវាលនៃរចនាសម្ព័ន្ធមួយទៅបន្ទាត់នីមួយៗនៃឯកសារ៖

ឯកសារ = fopen("fprintf.txt", "w");

while (scanf("%s%u%f", shop[i].name , & (shop[i].qty ), & (shop[i].price )) != EOF) ( fprintf (file, " %s %u %2f

, shop[i].name, shop[i].qty, shop[i].price);

ខ្ញុំ++;

)

មុខងារ fread() និង fwrite() យកជាប៉ារ៉ាម៉ែត្រ៖

  1. អាសយដ្ឋាននៃតំបន់អង្គចងចាំ ដែលទិន្នន័យត្រូវបានសរសេរ ឬអានពី,
  2. ទំហំនៃប្រភេទណាមួយដែលបានផ្តល់ឱ្យ
  3. ចំនួន​ទិន្នន័យ​ដែល​បាន​អាន​នៃ​ទំហំ​ដែល​បាន​បញ្ជាក់​,
  4. សន្ទស្សន៍ឯកសារ។

មុខងារទាំងនេះត្រឡប់ចំនួនទិន្នន័យដែលបានអាន ឬសរសេរដោយជោគជ័យ។ ទាំងនោះ។ អ្នកអាច "បញ្ជា" ការអានធាតុទិន្នន័យចំនួន 50 ប៉ុន្តែទទួលបានត្រឹមតែ 10 ប៉ុណ្ណោះ។ វានឹងមិនមានបញ្ហាអ្វីឡើយ។

ឧទាហរណ៍នៃការប្រើប្រាស់មុខងារ fread() និង fwrite()៖

# រួមបញ្ចូល # រួមបញ្ចូល main () ( ឯកសារ *; char shelf1[ 50 ], shelf2[ 100 ] ; int n, m; file = fopen ("shelf1.txt", "rb"); n= fread (shelf1, sizeof (char) , 50 , ឯកសារ ; fclose (ឯកសារ); ឯកសារ = fopen ("shelf2.txt", "rb"); \0 " ; \n" shelf2[m] = " \0 " ;

ធ្នើ2[ m+ 1 ] = "

;

  1. ឯកសារ = fopen("shop.txt", "wb");
  2. fwrite (strcat (shelf2, shelf1), sizeof (char), n+ m, file);

fclose (ឯកសារ);

)

នៅទីនេះការប៉ុនប៉ងមួយត្រូវបានធ្វើឡើងដើម្បីអាន 50 តួអក្សរពីឯកសារដំបូង។ n រក្សាទុកចំនួនតួអក្សរដែលបានអាន។ តម្លៃនៃ n អាចមាន 50 ឬតិចជាងនេះ។ ទិន្នន័យត្រូវបានដាក់ជាជួរ។ រឿងដដែលនេះកើតឡើងជាមួយឯកសារទីពីរ។ បន្ទាប់មក បន្ទាត់ទីមួយត្រូវបានបន្ថែមទៅទីពីរ ហើយទិន្នន័យត្រូវបានបោះចោលទៅក្នុងឯកសារទីបី។

ការដោះស្រាយបញ្ហា

សរសេរកម្មវិធីដែលសួរអ្នកប្រើប្រាស់នូវឈ្មោះ (អាសយដ្ឋាន) នៃឯកសារអត្ថបទ បន្ទាប់មកបើកវា ហើយរាប់ចំនួនតួអក្សរ និងបន្ទាត់នៅក្នុងនោះ។

សរសេរកម្មវិធីដែលសរសេរទៅទិន្នន័យឯកសារដែលបានទទួលពីឯកសារផ្សេងទៀត ហើយកែប្រែតាមវិធីខ្លះមុនពេលសរសេរ។ បន្ទាត់នីមួយៗនៃទិន្នន័យដែលទទួលបានពីឯកសារត្រូវតែសមនឹងរចនាសម្ព័ន្ធមួយ។

- ការប្រៀបធៀបដើម្បីកំណត់សមភាព ឬវិសមភាព។

គោលបំណងជាក់ស្តែងនៃការរាប់បញ្ចូលគឺដើម្បីកំណត់សំណុំនៃចំនួនថេរនិមិត្តសញ្ញាជាក់លាក់នៃប្រភេទចំនួនគត់។

ឧទាហរណ៍នៃការប្រើប្រាស់អថេរដែលបានរាប់បញ្ចូល៖

mo=1, tu, we, th, fr, sa, su) ថ្ងៃ;

puts("បញ្ចូលថ្ងៃនៃសប្តាហ៍ (ពី 1 ដល់ 7):"); scanf(“%d”, &t_day);

w_day = su; ចាប់ផ្តើម = mo;

បញ្ចប់ = w_day -t_day;

មានឯកសារពីរប្រភេទ៖ អត្ថបទ និងប្រព័ន្ធគោលពីរ។ ឯកសារអត្ថបទគឺជាលំដាប់នៃតួអក្សរ ASCII ហើយអាចត្រូវបានមើល និងកែសម្រួលដោយប្រើកម្មវិធីនិពន្ធអត្ថបទណាមួយ។

ឯកសារគោលពីរ (binary) គឺជាលំដាប់នៃទិន្នន័យ រចនាសម្ព័ន្ធដែលត្រូវបានកំណត់ដោយកម្មវិធី។

ភាសា C មានសំណុំមុខងារដ៏ធំមួយសម្រាប់ធ្វើការជាមួយឯកសារ ដែលភាគច្រើនត្រូវបានរកឃើញនៅក្នុងបណ្ណាល័យ stdio.h និង io.h ។

១៨.១. កំពុងបើកឯកសារ

ឯកសារនីមួយៗត្រូវបានកំណត់ឈ្មោះឡូជីខលខាងក្នុង ដែលត្រូវបានប្រើនៅពេលក្រោយនៅពេលចូលប្រើវា។ ឈ្មោះឡូជីខល (ឯកសារកំណត់អត្តសញ្ញាណ) គឺ

ចង្អុលទៅឯកសារ i.e. ទៅផ្ទៃអង្គចងចាំដែលមានព័ត៌មានចាំបាច់ទាំងអស់អំពីឯកសារ។ ទម្រង់ការប្រកាសទ្រនិចឯកសារមានដូចខាងក្រោម៖

ឯកសារ * ទ្រនិចទៅឯកសារ;

ឯកសារ - ឧបករណ៍កំណត់ប្រភេទរចនាសម្ព័ន្ធដែលបានពិពណ៌នានៅក្នុងបណ្ណាល័យស្តង់ដារ

stdio.h និងមានព័ត៌មានដូចខាងក្រោមៈ

ប្រភេទរចនាសម្ព័ន្ធ (

- ចំនួនបៃដែលមិនទាន់អានដែលនៅសេសសល់ក្នុងសតិបណ្ដោះអាសន្ន;

ទំហំផ្ទុកធម្មតាគឺ 512 បៃ; ដរាបណាកម្រិត = 0,

ប្លុកបន្ទាប់នៃទិន្នន័យត្រូវបានអានទៅក្នុងសតិបណ្ដោះអាសន្នពីឯកសារ។

- ទង់ស្ថានភាពឯកសារ - អាន សរសេរ បន្ថែម។

- ឯកសារពិពណ៌នា, ឧ។ លេខដែលកំណត់លេខរបស់វា -

ការកាន់កាប់ char ដែលមិនបានចុះហត្ថលេខា;

- តួអក្សរដែលមិនបានបញ្ជូន, i.e. ungetc-តួអក្សរ;

- ទំហំនៃសតិបណ្តោះអាសន្នខាងក្នុង;

unsigned char buffer;

- តម្លៃទ្រនិចសម្រាប់ការចូលប្រើខាងក្នុងសតិបណ្ដោះអាសន្ន ឧ។

បញ្ជាក់ការចាប់ផ្តើមនៃសតិបណ្ដោះអាសន្ន ការចាប់ផ្តើមនៃបន្ទាត់ ឬតម្លៃបច្ចុប្បន្ន

តម្លៃនៃទ្រនិចនៅខាងក្នុងសតិបណ្ដោះអាសន្នអាស្រ័យលើរបៀប

ម៉ា សតិបណ្ដោះអាសន្ន;

តួអក្សរដែលមិនបានចុះហត្ថលេខា * curp;

- តម្លៃបច្ចុប្បន្ននៃទ្រនិចសម្រាប់ការចូលប្រើនៅខាងក្នុង

ហ្វារ៉ា, ឧ។ បញ្ជាក់ទីតាំងបច្ចុប្បន្ននៅក្នុងសតិបណ្ដោះអាសន្ននៃការផ្លាស់ប្តូរ

នៅលើកម្មវិធី;

ដើមដែលមិនបានចុះហត្ថលេខា;

- ទង់ឯកសារបណ្តោះអាសន្ន;

- ទង់នៅពេលធ្វើការជាមួយឯកសារ;

) ឯកសារ;

មុនពេលអ្នកចាប់ផ្តើមធ្វើការជាមួយឯកសារ i.e. ដើម្បី​អាច​អាន ឬ​សរសេរ​ព័ត៌មាន​ទៅ​ឯកសារ វា​ត្រូវ​តែ​បើក​ដើម្បី​ចូល​ប្រើប្រាស់។ ចំពោះគោលបំណងនេះមុខងារត្រូវបានប្រើជាធម្មតា

FILE* fopen(char* file_name, char* mode);

វាត្រូវការតំណាងខាងក្រៅ - ឈ្មោះរូបវន្តនៃឯកសារនៅលើឧបករណ៍ផ្ទុក (ថាសទន់ ថាសរឹង) ហើយផ្គូផ្គងវាជាមួយឈ្មោះឡូជីខល។

ឈ្មោះរាងកាយ, i.e. ឈ្មោះឯកសារ និងផ្លូវទៅកាន់វាត្រូវបានបញ្ជាក់ដោយប៉ារ៉ាម៉ែត្រទីមួយ

- បន្ទាត់ឧទាហរណ៍ "a:Mas_dat.dat" - ឯកសារមួយឈ្មោះ Mas_dat.dat ដែលមានទីតាំងនៅលើថាសទន់ "d:\\work\\ Sved.txt" - ឯកសារដែលមានឈ្មោះថា Sved.txt ដែលមានទីតាំងនៅលើ Hard បើកបរក្នុងថតការងារ។

យកចិត្តទុកដាក់! backslash (\) ជាតួអក្សរពិសេសត្រូវបានសរសេរពីរដងក្នុងមួយជួរ។

នៅពេលបើកដោយជោគជ័យ មុខងារ fopen ត្រឡប់ទ្រនិចមួយទៅឯកសារ (តទៅនេះហៅថា ទ្រនិចឯកសារ) ។ មានកំហុស NULL ត្រូវបានបញ្ជូនមកវិញ។ ស្ថានភាពនេះជាធម្មតាកើតឡើងនៅពេលដែលផ្លូវទៅកាន់ឯកសារដែលត្រូវបើកត្រូវបានបញ្ជាក់មិនត្រឹមត្រូវ។ ឧទាហរណ៍ ប្រសិនបើនៅក្នុងថ្នាក់បង្ហាញនៃសាកលវិទ្យាល័យរបស់យើង អ្នកបញ្ជាក់ផ្លូវដែលត្រូវបានហាមឃាត់សម្រាប់ការសរសេរ (ជាធម្មតា d:\work\ ត្រូវបានអនុញ្ញាត)។

ប៉ារ៉ាម៉ែត្រទីពីរគឺជាបន្ទាត់ដែលបញ្ជាក់របៀបចូលប្រើឯកសារ៖

w - ឯកសារត្រូវបានបើកសម្រាប់ការសរសេរ; ប្រសិនបើមិនមានឯកសារដែលមានឈ្មោះដែលបានផ្តល់ឱ្យនោះវានឹងត្រូវបានបង្កើត។ ប្រសិនបើឯកសារបែបនេះមាន នោះព័ត៌មានពីមុនត្រូវបានបំផ្លាញមុនពេលបើក។

r - ឯកសារបើកសម្រាប់តែអាន។ ប្រសិនបើមិនមានឯកសារបែបនេះទេ កំហុសកើតឡើង។

a – ឯកសារត្រូវបានបើកដើម្បីបន្ថែមព័ត៌មានថ្មីដល់ទីបញ្ចប់។

r+ – ឯកសារត្រូវបានបើកសម្រាប់កែសម្រួលទិន្នន័យ – ទាំងការសរសេរ និងការអានព័ត៌មានគឺអាចធ្វើទៅបាន។

w+ - ដូចគ្នានឹង r+;

a+ – ដូចគ្នានឹង a ដែរ មានតែការសរសេរអាចធ្វើទៅបានគ្រប់ទីកន្លែងក្នុងឯកសារ។ ការអានឯកសារក៏មានផងដែរ។

t - ឯកសារបើកក្នុងរបៀបអត្ថបទ ខ - ឯកសារបើកក្នុងរបៀបគោលពីរ។

របៀបអត្ថបទខុសពីរបៀបប្រព័ន្ធគោលពីរ ដែលនៅពេលឯកសារត្រូវបានបើកជាគូអត្ថបទនៃតួអក្សរ "line feed" "carriage return" ត្រូវបានជំនួសដោយតួអក្សរតែមួយ៖ "line feed" សម្រាប់មុខងារទាំងអស់សម្រាប់ការសរសេរទិន្នន័យទៅកាន់ឯកសារ និង សម្រាប់មុខងារលទ្ធផលទាំងអស់ តួអក្សរ “line feed” "ឥឡូវត្រូវបានជំនួសដោយតួអក្សរពីរ៖ "line feed", "carriage return" ។

តាមលំនាំដើម ឯកសារបើកក្នុងរបៀបអត្ថបទ។ ឧទាហរណ៍៖ ឯកសារ *f; - ទ្រនិចសម្រាប់ឯកសារ f ត្រូវបានប្រកាស;

f = fopen("d:\\work\\Dat_sp.cpp", "w"); - ឯកសារដែលមានឈ្មោះឡូជីខល f ដែលមានឈ្មោះពិត Dat_sp.cpp ដែលមានទីតាំងនៅលើ drive d ក្នុងថតការងារត្រូវបានបើកសម្រាប់ការសរសេរ។ ឬខ្លីជាងនេះ។

ឯកសារ * f = fopen("d:\\work\\Dat_sp.cpp", "w");

១៨.២. ការបិទឯកសារ

បន្ទាប់ពីធ្វើការជាមួយឯកសារ ការចូលប្រើវាត្រូវតែបិទ។ នេះត្រូវបានធ្វើដោយមុខងារ int fclose (ទ្រនិចឯកសារ) ។ ឧទាហរណ៍ពីឧទាហរណ៍មុនឯកសារត្រូវបានបិទដូចនេះ: fclose (f);

ដើម្បីបិទឯកសារច្រើន មុខងារមួយត្រូវបានណែនាំ ប្រកាសដូចខាងក្រោម៖ void fcloseall (void);

ប្រសិនបើអ្នកត្រូវការផ្លាស់ប្តូររបៀបចូលប្រើសម្រាប់ឯកសារមួយ អ្នកត្រូវតែបិទឯកសារជាមុនសិន រួចបើកវាម្តងទៀត ប៉ុន្តែមានសិទ្ធិចូលប្រើផ្សេង។ ដើម្បីធ្វើដូចនេះសូមប្រើមុខងារស្តង់ដារ៖

ឯកសារ * បើកដោយសេរី (char*file_name, char *mode, FILE *file_pointer);

មុខងារនេះបិទឯកសារដែលបានប្រកាសជាមុនសិន file_pointer(ដូចដែលមុខងារ fopen ធ្វើ) ហើយបន្ទាប់មកបើកឯកសារដោយឈ្មោះឯកសារ និងការអនុញ្ញាត "mode"។

ភាសា C មានសមត្ថភាពក្នុងការធ្វើការជាមួយឯកសារបណ្តោះអាសន្នដែលត្រូវការតែខណៈពេលដែលកម្មវិធីកំពុងដំណើរការ។ ក្នុងករណីនេះមុខងារត្រូវបានប្រើ

ឯកសារ * tmpfile (ទុកជាមោឃៈ);

ដែលបង្កើតឯកសារបណ្តោះអាសន្ននៅលើថាសដែលមានសិទ្ធិចូលប្រើ “w+b” បន្ទាប់ពីកម្មវិធីត្រូវបានបញ្ចប់ ឬបន្ទាប់ពីឯកសារបណ្តោះអាសន្នត្រូវបានបិទ វាត្រូវបានលុបដោយស្វ័យប្រវត្តិ។

១៨.៣. សរសេរ - អានព័ត៌មាន

សកម្មភាពទាំងអស់សម្រាប់ការអាន និងសរសេរទិន្នន័យទៅកាន់ឯកសារមួយអាចត្រូវបានបែងចែកជាបីក្រុម៖ ប្រតិបត្តិការបញ្ចូល-លទ្ធផលតួអក្សរតាមតួអក្សរ។ ប្រតិបត្តិការ I/O មួយជួរ; រារាំងប្រតិបត្តិការ I/O ។

សូមក្រឡេកមើលមុខងារសំខាន់ៗដែលប្រើក្នុងក្រុមនីមួយៗនៃប្រតិបត្តិការទាំងបីនេះ។

តួអក្សរតាមតួអក្សរ I/O

នៅក្នុងមុខងារ I/O តួអក្សរមួយតួអក្សរត្រូវបានទទួលពីឯកសារ ឬតួអក្សរមួយត្រូវបានផ្ញើទៅឯកសារមួយ៖

ជួរ I/O

មុខងារ Line I/O ផ្ទេរពីឯកសារ ឬទៅ

រារាំង I/O

មុខងារ Block I/O ដំណើរការលើប្លុកទាំងមូល

ព័ត៌មាន៖

int fread (void * p, intsize,

- អាន n ប្លុកនៃទំហំបៃនីមួយៗពីឯកសារ

int n, ឯកសារ * f)

la f ទៅ​កន្លែង​ចងចាំ​ជាមួយ​ទ្រនិច p (ទាមទារ

int fwrite (void * p, intsize,

បែងចែកអង្គចងចាំជាមុនសម្រាប់ប្លុកដែលត្រូវអាន);

- សរសេរ n ប្លុកនៃទំហំបៃនីមួយៗពី

int n, ឯកសារ * f)

តំបន់អង្គចងចាំជាមួយទ្រនិច p ដើម្បីឯកសារ f ។

ទម្រង់ I/O ត្រូវបានផលិតដោយមុខងារ។

ដើម្បីភាពងាយស្រួល ព័ត៌មាននៅក្នុងឧបករណ៍ផ្ទុកត្រូវបានរក្សាទុកក្នុងទម្រង់ជាឯកសារ។

ឯកសារគឺជាតំបន់ដែលមានឈ្មោះនៃអង្គចងចាំខាងក្រៅដែលបានបម្រុងទុកសម្រាប់ការរក្សាទុកអារេនៃទិន្នន័យ។ ទិន្នន័យដែលមាននៅក្នុងឯកសារមានលក្ខណៈចម្រុះណាស់៖ កម្មវិធីក្នុងក្បួនដោះស្រាយ ឬភាសាម៉ាស៊ីន។ ទិន្នន័យដំបូងសម្រាប់ប្រតិបត្តិការកម្មវិធី ឬលទ្ធផលនៃការអនុវត្តកម្មវិធី; អត្ថបទឥតគិតថ្លៃ; រូបភាពក្រាហ្វិកជាដើម។

ថតឯកសារ (ថតឯកសារ) - បណ្តុំនៃបៃដែលមានឈ្មោះនៅលើឧបករណ៍ផ្ទុកដែលមានឈ្មោះនៃថតរង និងឯកសារ ដែលប្រើក្នុងប្រព័ន្ធឯកសារ ដើម្បីសម្រួលដល់ការរៀបចំឯកសារ។

ប្រព័ន្ធឯកសារហៅថាផ្នែកមុខងារនៃប្រព័ន្ធប្រតិបត្តិការដែលធ្វើប្រតិបត្តិការលើឯកសារ។ ឧទាហរណ៍នៃប្រព័ន្ធឯកសារគឺ FAT (FAT - តារាងបែងចែកឯកសារ), NTFS, UDF (ប្រើនៅលើស៊ីឌី) ។

មានកំណែសំខាន់ៗចំនួនបីនៃ FAT គឺ FAT12 FAT16 និង FAT32 ។ ពួកវាខុសគ្នានៅក្នុងជម្រៅប៊ីតនៃកំណត់ត្រានៅក្នុងរចនាសម្ព័ន្ធថាស ពោលគឺឧ។ ចំនួនប៊ីតដែលបានបែងចែកដើម្បីរក្សាទុកលេខចង្កោម។ FAT12 ត្រូវបានប្រើជាចម្បងសម្រាប់ថាសទន់ (រហូតដល់ 4 KB) FAT16 - សម្រាប់ថាសដែលមានសមត្ថភាពតូច FAT32 - សម្រាប់ដ្រាយ FLASH ដែលមានសមត្ថភាពខ្ពស់ (រហូតដល់ 32 GB) ។

សូមក្រឡេកមើលរចនាសម្ព័ន្ធនៃប្រព័ន្ធឯកសារដោយប្រើ FAT32 ជាឧទាហរណ៍។

រចនាសម្ព័ន្ធឯកសារ FAT32

ឧបករណ៍អង្គចងចាំខាងក្រៅនៅក្នុងប្រព័ន្ធ FAT32 មានអាសយដ្ឋានប្លុកជាជាងអាសយដ្ឋានបៃ។ ព័ត៌មានត្រូវបានសរសេរទៅឧបករណ៍អង្គចងចាំខាងក្រៅនៅក្នុងប្លុក ឬផ្នែក។

វិស័យគឺជាអង្គភាពផ្ទុកព័ត៌មានដែលអាចអាសយដ្ឋានបានអប្បបរមានៅលើឧបករណ៍ផ្ទុកខាងក្រៅ។ ជាធម្មតា ទំហំផ្នែកត្រូវបានជួសជុលនៅ 512 បៃ។ ដើម្បីបង្កើនទំហំអាសយដ្ឋាននៃឧបករណ៍អង្គចងចាំខាងក្រៅ វិស័យត្រូវបានបញ្ចូលគ្នាជាក្រុមដែលហៅថាចង្កោម។

ចង្កោមគឺជាសហជីពនៃវិស័យជាច្រើន ដែលអាចចាត់ទុកថាជាអង្គភាពឯករាជ្យដែលមានលក្ខណៈសម្បត្តិជាក់លាក់។ ទ្រព្យសម្បត្តិសំខាន់នៃចង្កោមគឺទំហំរបស់វា វាស់ជាចំនួនផ្នែក ឬចំនួនបៃ។

ប្រព័ន្ធឯកសារ FAT32 មានរចនាសម្ព័ន្ធដូចខាងក្រោម។

ចង្កោមដែលប្រើសម្រាប់ការសរសេរឯកសារត្រូវបានដាក់លេខដោយចាប់ផ្តើមពីលេខ 2។ តាមក្បួន ចង្កោមលេខ 2 ត្រូវបានប្រើដោយថតឫស ហើយចាប់ផ្តើមពីចង្កោមលេខ 3 អារេទិន្នន័យត្រូវបានរក្សាទុក។ វិស័យដែលប្រើដើម្បីរក្សាទុកព័ត៌មាននៅខាងលើថតឫសមិនត្រូវបានចង្កោមទេ។
ទំហំឯកសារអប្បបរមាដែលត្រូវការនៅលើថាសត្រូវគ្នានឹង 1 ចង្កោម។

ផ្នែកចាប់ផ្ដើមចាប់ផ្តើមដោយព័ត៌មានខាងក្រោម៖

  • EB 58 90 - លោតដោយគ្មានលក្ខខណ្ឌ និងហត្ថលេខា;
  • 4D 53 44 4F 53 35 2E 30 MSDOS5.0;
  • 00 02 - ចំនួនបៃក្នុងវិស័យ (ជាធម្មតា 512);
  • 1 បៃ - ចំនួននៃផ្នែកនៅក្នុងចង្កោម;
  • 2 បៃ - ចំនួននៃផ្នែកបម្រុង។

លើសពីនេះ ផ្នែកចាប់ផ្ដើមមានព័ត៌មានសំខាន់ៗដូចខាងក្រោម៖

  • 0x10 (1 បៃ) - ចំនួនតារាង FAT (ជាធម្មតា 2);
  • 0x20 (4 បៃ) - ចំនួននៃផ្នែកនៅលើថាស;
  • 0x2С (4 បៃ) - ចំនួនចង្កោមនៃថតឫស;
  • 0x47 (11 បៃ) - ស្លាកកម្រិតសំឡេង;
  • 0x1FE (2 បៃ) - ហត្ថលេខាផ្នែកចាប់ផ្ដើម (55 AA) ។

ផ្នែកព័ត៌មានប្រព័ន្ធឯកសារមាន៖

  • 0x00 (4 បៃ) - ហត្ថលេខា (52 52 61 41);
  • 0x1E4 (4 បៃ) - ហត្ថលេខា (72 72 41 61);
  • 0x1E8 (4 បៃ) - ចំនួននៃចង្កោមឥតគិតថ្លៃ, -1 ប្រសិនបើមិនស្គាល់;
  • 0x1EC (4 បៃ) - ចំនួននៃចង្កោមដែលបានកត់ត្រាចុងក្រោយ;
  • 0x1FE (2 បៃ) - ហត្ថលេខា (55 AA) ។

តារាង FAT មានព័ត៌មានអំពីស្ថានភាពនៃចង្កោមនីមួយៗនៅលើថាស។ 2 បៃទាបនៃតារាង FAT រក្សាទុក F8 FF FF 0F FF FF FF FF FF (ដែលត្រូវនឹងស្ថានភាពនៃចង្កោម 0 និង 1 ដែលអវត្តមានរាងកាយ) ។ លើសពីនេះ ស្ថានភាពនៃចង្កោមនីមួយៗមានចំនួននៃចង្កោមដែលឯកសារបច្ចុប្បន្នបន្ត ឬព័ត៌មានខាងក្រោម៖

  • 00 00 00 00 - ចង្កោមគឺឥតគិតថ្លៃ;
  • FF FF FF 0F - ចុងបញ្ចប់នៃឯកសារបច្ចុប្បន្ន។
  • 8 បៃ - ឈ្មោះឯកសារ;
  • 3 បៃ - ផ្នែកបន្ថែមឯកសារ;

ថត root មានសំណុំនៃកំណត់ត្រាព័ត៌មាន 32 ប៊ីតអំពីឯកសារនីមួយៗដែលមានព័ត៌មានដូចខាងក្រោមៈ

នៅពេលធ្វើការជាមួយឈ្មោះឯកសារវែង (រួមទាំងឈ្មោះរុស្ស៊ី) ឈ្មោះឯកសារត្រូវបានអ៊ិនកូដដោយប្រើប្រព័ន្ធអ៊ិនកូដ UTF-16 ។ ក្នុងករណីនេះ 2 បៃត្រូវបានបម្រុងទុកសម្រាប់ការអ៊ិនកូដតួអក្សរនីមួយៗ។ ក្នុងករណីនេះ ឈ្មោះឯកសារត្រូវបានសរសេរក្នុងរចនាសម្ព័ន្ធដូចខាងក្រោមៈ

  • 1 បៃលំដាប់;
  • 10 បៃមានតួអក្សរ 5 ទាបនៃឈ្មោះឯកសារ។
  • គុណលក្ខណៈ 1 បៃ;
  • 1 បៃបានបម្រុងទុក;
  • 1 បៃ - ឈ្មោះ DOS checksum;
  • 12 បៃមានតួអក្សរ 3 ទាបនៃឈ្មោះឯកសារ។
  • 2 បៃ - ចំនួននៃចង្កោមដំបូង;
  • តួអក្សរដែលនៅសល់នៃឈ្មោះវែង។

ធ្វើការជាមួយឯកសារជាភាសា C

ចំពោះអ្នកសរសេរកម្មវិធី ឯកសារបើកចំហត្រូវបានតំណាងជាលំដាប់នៃទិន្នន័យដែលកំពុងអាន ឬសរសេរ។ នៅពេលដែលឯកសារត្រូវបានបើក វាត្រូវបានភ្ជាប់ជាមួយ ស្ទ្រីម I/O. ព័ត៌មានលទ្ធផលត្រូវបានសរសេរទៅស្ទ្រីម ព័ត៌មានបញ្ចូលត្រូវបានអានពីស្ទ្រីម។

នៅពេលដែលស្ទ្រីមត្រូវបានបើកសម្រាប់ I/O វាត្រូវបានភ្ជាប់ជាមួយរចនាសម្ព័ន្ធ FILE ស្តង់ដារ ដែលត្រូវបានកំណត់នៅក្នុង stdio.h ។ រចនាសម្ព័ន្ធ FILE មានព័ត៌មានចាំបាច់អំពីឯកសារ។

ការបើកឯកសារត្រូវបានធ្វើដោយប្រើមុខងារ fopen() ដែលត្រឡប់ទ្រនិចទៅរចនាសម្ព័ន្ធ FILE ដែលអាចត្រូវបានប្រើសម្រាប់ប្រតិបត្តិការជាបន្តបន្ទាប់នៅលើឯកសារ។

ឯកសារ * fopen (ឈ្មោះ, ប្រភេទ);


ឈ្មោះ - ឈ្មោះឯកសារដែលត្រូវបើក ​​(រួមទាំងផ្លូវ)
ប្រភេទគឺជាទ្រនិចទៅខ្សែអក្សរដែលកំណត់ពីរបៀបដែលឯកសារត្រូវបានចូលប្រើ៖
  • "r" - បើកឯកសារសម្រាប់ការអាន (ឯកសារត្រូវតែមាន);
  • "w" - បើកឯកសារទទេសម្រាប់ការសរសេរ; ប្រសិនបើឯកសារមាន មាតិការបស់វាត្រូវបានបាត់បង់។
  • "a" - បើកឯកសារសម្រាប់ការសរសេរដល់ទីបញ្ចប់ (សម្រាប់បន្ថែម); ឯកសារត្រូវបានបង្កើតប្រសិនបើវាមិនមាន;
  • "r+" - បើកឯកសារសម្រាប់អាននិងសរសេរ (ឯកសារត្រូវតែមាន);
  • "w+" - បើកឯកសារទទេសម្រាប់អាននិងសរសេរ; ប្រសិនបើឯកសារមាន មាតិការបស់វាត្រូវបានបាត់បង់។
  • "a+" - បើកឯកសារសម្រាប់អាន និងបន្ថែម ប្រសិនបើឯកសារមិនមានទេ នោះវាត្រូវបានបង្កើត។

តម្លៃត្រឡប់គឺជាទ្រនិចទៅស្ទ្រីមបើកចំហ។ ប្រសិនបើកំហុសត្រូវបានជួបប្រទះ NULL ត្រូវបានត្រឡប់។

មុខងារ fclose() បិទស្ទ្រីម ឬស្ទ្រីមដែលភ្ជាប់ជាមួយឯកសារដែលបានបើកដោយប្រើមុខងារ fopen()។ ចរន្តដែលត្រូវបិទត្រូវបានកំណត់ដោយអាគុយម៉ង់នៃមុខងារ fclose() ។

តម្លៃត្រឡប់៖ តម្លៃ 0 ប្រសិនបើស្ទ្រីមត្រូវបានបិទដោយជោគជ័យ។ EOF ថេរប្រសិនបើមានកំហុសកើតឡើង។

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# រួមបញ្ចូល
int main()(
ឯកសារ * fp;
ឈ្មោះ char = "my.txt" ;
ប្រសិនបើ ((fp = fopen(ឈ្មោះ "r" )) == NULL)
{
printf( "បរាជ័យក្នុងការបើកឯកសារ");
getchar();
ត្រឡប់ 0;
}
// ជោគជ័យក្នុងការបើកឯកសារ
... // សកម្មភាពដែលត្រូវការលើទិន្នន័យ
fclose(fp);
getchar();
ត្រឡប់ 0;
}

ការអានតួអក្សរពីឯកសារ:

char fgetc (ស្ទ្រីម);


អាគុយម៉ង់មុខងារគឺជាទ្រនិចទៅចរន្តនៃប្រភេទ FILE ។ អនុគមន៍​ត្រឡប់​កូដ​តួអក្សរ​ដែល​បាន​អាន។ ប្រសិនបើការបញ្ចប់នៃឯកសារត្រូវបានឈានដល់ ឬមានកំហុសកើតឡើង នោះ EOF ថេរត្រូវបានត្រឡប់មកវិញ។

ការសរសេរនិមិត្តសញ្ញាទៅឯកសារ:

fputc (char, ស្ទ្រីម);

អាគុយម៉ង់របស់មុខងារគឺជាតួអក្សរ និងចង្អុលទៅស្ទ្រីមនៃប្រភេទ FILE ។ អនុគមន៍​ត្រឡប់​កូដ​តួអក្សរ​ដែល​បាន​អាន។

មុខងារ fscanf() និង fprintf() គឺស្រដៀងគ្នាទៅនឹងមុខងារ scanf() និង printf() ប៉ុន្តែធ្វើការជាមួយឯកសារទិន្នន័យ ហើយមានទ្រនិចទៅឯកសារជាអាគុយម៉ង់ដំបូងរបស់ពួកគេ។

fscanf (ស្ទ្រីម "ទម្រង់បញ្ចូល" អាគុយម៉ង់);

យន្តការ I/O ដែលបង្កើតឡើងដោយ , មិនអនុលោមតាមរចនាប័ទ្មដែលទទួលយកជាទូទៅនៃការសរសេរកម្មវិធីតម្រង់ទិសវត្ថុនាពេលបច្ចុប្បន្ននេះ លើសពីនេះ វាប្រើប្រាស់ប្រតិបត្តិការទ្រនិចយ៉ាងខ្លាំង ដែលត្រូវបានចាត់ទុកថាមិនមានសុវត្ថិភាពនៅក្នុងបរិយាកាសប្រតិបត្តិកូដសុវត្ថិភាពទំនើប។ ជម្រើសមួយនៅពេលបង្កើតកម្មវិធីកម្មវិធីគឺជាយន្តការនៃថ្នាក់ I/O ស្តង់ដារដែលផ្តល់ដោយស្តង់ដារភាសា C++ ។

ការបើកឯកសារ

ថ្នាក់ដែលប្រើជាទូទៅបំផុតគឺ ifstream សម្រាប់អាន, ofstream សម្រាប់ការសរសេរ និង fstream សម្រាប់កែប្រែឯកសារ។

ថ្នាក់ I/O ទាំងអស់ត្រូវបានទាញយកដោយប្រយោលពី ios បុព្វបុរសទូទៅ ដោយទទួលមរតកមុខងាររបស់វាយ៉ាងពេញលេញ។ ដូច្នេះ របៀបបើកឯកសារត្រូវបានបញ្ជាក់ដោយសមាជិកទិន្នន័យនៃប្រភេទការរាប់បញ្ចូល open_mode ដែលត្រូវបានកំណត់ដូចខាងក្រោម៖

Enum open_mode (កម្មវិធី, ប្រព័ន្ធគោលពីរ, ចូល, ចេញ, trunc, ញ៉ាំ );

ខាងក្រោមនេះគឺជាតម្លៃដែលអាចធ្វើបាននៃទង់ជាតិ និងគោលបំណងរបស់វា។

ឧទាហរណ៍ ដើម្បីបើកឯកសារដែលមានឈ្មោះថា test.txt ដើម្បីអានទិន្នន័យក្នុងទម្រង់គោលពីរ អ្នកនឹងសរសេរ៖

ឯកសារ ifstream; file.open("test.txt", ios::in | ios::binary);

ប្រតិបត្តិករ OR ឡូជីខល (|) អនុញ្ញាតឱ្យអ្នកបង្កើតរបៀបមួយជាមួយនឹងការរួមបញ្ចូលគ្នានៃទង់ណាមួយ។ ដូច្នេះ ដើម្បីឱ្យនៅពេលបើកឯកសារដោយធាតុ អ្នកមិនសរសេរជាន់លើឯកសារដែលមានស្រាប់ដោយចៃដន្យទេ អ្នកត្រូវតែប្រើទម្រង់ខាងក្រោម៖

ឯកសារក្រៅបណ្តាញ; file.open("test.txt", ios::out | ios::app);

វាត្រូវបានសន្មត់ថាឯកសារបឋមកថាដែលត្រូវគ្នាត្រូវបានរួមបញ្ចូលនៅក្នុងគម្រោង៖

# រួមបញ្ចូល

ដើម្បីពិនិត្យមើលថាតើឯកសារត្រូវបានបើកដោយជោគជ័យ អ្នកអាចប្រើការស្ថាបនា

ប្រសិនបើ (! ឯកសារ) ( // កំហុសក្នុងការបើកឯកសារ)

ប្រតិបត្តិករបញ្ចូល និងស្រង់ចេញ

បដិសេធក្នុងថ្នាក់គ្រប់គ្រងឯកសារ ប្រតិបត្តិកររួមបញ្ចូល (<<) записывает данные в файловый поток. Как только вы открыли файл для записи, можно записывать в него текстовую строку целиком:

ឯកសារ<< "Это строка текста";

អ្នកក៏អាចសរសេរខ្សែអក្សរជាផ្នែកៗបានដែរ៖

ឯកសារ<< "Это " << "строка " << "текста";

សេចក្តីថ្លែងការណ៍ endl បញ្ចប់ការបញ្ចូលបន្ទាត់ជាមួយនឹងការបញ្ជូនត្រឡប់មកវិញ:

ឯកសារ<< "Это строка текста" << endl;

ដោយប្រើ រួមបញ្ចូល ប្រតិបត្តិករ វាងាយស្រួលក្នុងការសរសេរតម្លៃនៃអថេរ ឬធាតុអារេទៅឯកសារមួយ៖

ឯកសារក្រៅបណ្តាញ ("Temp.txt"); char buff = "អារេអត្ថបទមានអថេរ"; int vx = 100; float pi = 3.14159; ឯកសារ<< buff << endl << vx << endl << pi << endl;

ជាលទ្ធផលនៃការប្រតិបត្តិកូដនោះ បន្ទាត់បីនៃឯកសារអត្ថបទ Temp.txt ត្រូវបានបង្កើតឡើង៖

អារេអត្ថបទមានអថេរ 100 3.14159

ចំណាំថាតម្លៃលេខត្រូវបានសរសេរទៅឯកសារជាខ្សែអក្សរជាជាងតម្លៃគោលពីរ។

ប្រតិបត្តិករទាញយក(>>) បង្កើតផលផ្ទុយ។ វាហាក់ដូចជាថា ដើម្បីស្រង់តួអក្សរចេញពីឯកសារ Temp.txt ដែលបានសរសេរពីមុន អ្នកនឹងសរសេរកូដដូចខាងក្រោម៖

ឯកសារ ifstream("Temp.txt"); char buff; int vx; អណ្តែត pi; ឯកសារ >> buff >> vx >> pi;

ទោះយ៉ាងណាក៏ដោយ ប្រតិបត្តិករស្រង់ចេញនឹងឈប់នៅការកំណត់ព្រំដែនដំបូងដែលវាជួបប្រទះ (ចន្លោះ ផ្ទាំង ឬបន្ទាត់ថ្មី)។ ដូច្នេះនៅពេលញែកប្រយោគ "អារេអត្ថបទមានអថេរ" មានតែពាក្យ "អត្ថបទ" នឹងត្រូវបានសរសេរទៅអារេ buff ចន្លោះមិនត្រូវបានអើពើ ហើយពាក្យ "អារេ" នឹងក្លាយជាតម្លៃនៃអថេរ vx ទាំងមូល និងកូដ។ ការប្រតិបត្តិនឹង "ខុស" ជាមួយនឹងការរំលោភលើរចនាសម្ព័ន្ធទិន្នន័យដែលជៀសមិនរួច។ បន្ទាប់នៅពេលពិភាក្សាអំពីថ្នាក់ ifstream យើងនឹងបង្ហាញពីរបៀបរៀបចំការអានឯកសារឱ្យបានត្រឹមត្រូវពីឧទាហរណ៍មុន។

ថ្នាក់ ifstream៖ ការអានឯកសារ

ដូចដែលឈ្មោះបានបង្ហាញ ថ្នាក់ ifstream ត្រូវបានរចនាឡើងដើម្បីបញ្ចូលស្ទ្រីមឯកសារ។ វិធីសាស្រ្តសំខាន់ៗនៃថ្នាក់ត្រូវបានរាយខាងក្រោម។ ភាគច្រើននៃពួកគេត្រូវបានទទួលមរតកពីថ្នាក់ istream និងផ្ទុកលើសទម្ងន់ ដើម្បីពង្រីកមុខងារមេ។ ឧទាហរណ៍ មុខងារ get អាស្រ័យលើប៉ារ៉ាម៉ែត្រហៅអាចអានមិនត្រឹមតែតួអក្សរតែមួយប៉ុណ្ណោះទេប៉ុន្តែថែមទាំងប្លុកតួអក្សរផងដែរ។

ឥឡូវនេះវាច្បាស់អំពីរបៀបដែលឧទាហរណ៍មុនត្រូវកែប្រែ ដូច្នេះការប្រើប្រតិបត្តិករទាញយកទិន្នន័យផ្តល់លទ្ធផលរំពឹងទុក៖

ឯកសារ ifstream("Temp.txt"); char buff; int vx; អណ្តែត pi; file.getline(buff, sizeof(buff)); ឯកសារ >> vx >> pi:

វិធីសាស្ត្រ getline នឹងអានបន្ទាត់ទីមួយនៃឯកសារដល់ទីបញ្ចប់ ហើយប្រតិបត្តិករ >> នឹងផ្តល់តម្លៃទៅអថេរ។

ឧទាហរណ៍ខាងក្រោមបង្ហាញការបន្ថែមទិន្នន័យទៅឯកសារអត្ថបទ ហើយបន្ទាប់មកអានឯកសារទាំងមូល។ A while(1) loop ត្រូវបានប្រើជំនួសឱ្យ while(!file2.eof()) សម្រាប់ហេតុផលដែលបានពិភាក្សានៅក្នុង .

# រួមបញ្ចូល # រួមបញ្ចូល ដោយប្រើ namespace std; int main() ( ofstream file; file.open("test.txt",ios::out|ios::app); if (!file) ( cout<< "File error - can"t open to write data!"; cin.sync(); cin.get(); return 1; } for (int i=0; i<10; i++) file << i << endl; file.close(); ifstream file2; file2.open("test.txt", ios::in); if (!file2) { cout << "File error - can"t open to read data!"; cin.sync(); cin.get(); return 2; } int a,k=0; while (1) { file2 >> ក;<< a << " "; k++; } cout << endl << "K=" << k << endl; file2.close(); cin.sync(); cin.get(); return 0; }

ប្រសិនបើ (file2.eof()) បំបែក;

# រួមបញ្ចូល # រួមបញ្ចូល cout<< str << endl; // вывод прочитанной строки на экран cin.sync(); cin.get(); return 0; }

ឧទាហរណ៍ខាងក្រោមបង្ហាញរង្វិលជុំដែលអានបន្ទាត់ពីឯកសារ test.txt ហើយបង្ហាញពួកវានៅលើកុងសូល។

ដោយប្រើ namespace std; int main() ( ifstream file; // create a stream object file file.open("test.txt"); // បើកឯកសារសម្រាប់អាន if (!file) return 1; // return on open error char str; // បណ្តុំបន្ទាត់ឋិតិវន្ត // អាន និងបង្ហាញបន្ទាត់ក្នុងរង្វិលជុំរហូតដល់ eof while (!file.getline(str, sizeof(str)).eof()) cout<< str << endl; }

កូដនេះនៅក្រោមប្រព័ន្ធប្រតិបត្តិការ Windows ក៏អាស្រ័យទៅលើវត្តមាននៃតួអក្សរបន្ទាត់ថ្មីនៅក្នុងជួរចុងក្រោយនៃឯកសារ វានឹងកាន់តែអាចទុកចិត្តបានក្នុងការធ្វើដូចនេះ៖

ខណៈ (1) (ប្រសិនបើ (file.eof()) បំបែក; file.getline(str, sizeof(str)); cout

ការហៅទូរសព្ទយ៉ាងច្បាស់លាស់ទៅកាន់វិធីសាស្ត្របើក និងបិទមិនត្រូវបានទាមទារទេ។ ជាការពិតណាស់ ការហៅអ្នកសាងសង់ដោយប្រើអាគុយម៉ង់អនុញ្ញាតឱ្យអ្នកបើកឯកសារភ្លាមៗនៅពេលបង្កើតវត្ថុឯកសារដែលមានខ្សែស្រឡាយ៖

ឯកសារ ifstream ("test.txt");

ជំនួសឱ្យវិធីសាស្ត្របិទ អ្នកអាចប្រើ Delete operator ដែលនឹងហៅទៅអ្នកបំផ្លាញវត្ថុឯកសារដោយស្វ័យប្រវត្តិ ហើយបិទឯកសារ។ កូដ while loop ធានាបាននូវការត្រួតពិនិត្យឯកសារបញ្ចប់ត្រឹមត្រូវ។

ថ្នាក់នៃចរន្ត៖ ការសរសេរឯកសារ

ថ្នាក់ ofstream ត្រូវបានរចនាឡើងដើម្បីបញ្ចេញទិន្នន័យពីស្ទ្រីមឯកសារ។ ខាងក្រោម​នេះ​រាយ​វិធី​ចម្បង​នៃ​ថ្នាក់​នេះ។<=3; i++) file << "Строка " << i << endl; file.close();

ប្រតិបត្តិកររួមបញ្ចូលដែលបានពិពណ៌នាពីមុនគឺងាយស្រួលសម្រាប់រៀបចំការសរសេរទៅឯកសារអត្ថបទ៖

ឯកសារក្រៅបណ្តាញ("temp.txt"); ប្រសិនបើ (!file) ត្រឡប់; សម្រាប់ (int i=1; i

ឯកសារគោលពីរ

# រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល ដោយប្រើ namespace std; struct Notes ( // រចនាសម្ព័ន្ធទិន្នន័យសៀវភៅកត់ត្រា char Name; // ឈ្មោះពេញ char Phone; // phone int Age; // age ); int main() ( setlocale(LC_ALL, "Russian"); Notes Note1= ("The Terrible Ioann Vasilyevich", "not installed", 60); Notes Note2= ("Godunov Boris Fedorovich", "095-111-2233" , 30 ); Notes Note3= ("Romanov Petr Mikhailovich", "812-333-2211", 20 ); sizeof (Notes)); // ប្លុកទី 1 ofile.write((char*)&Note2, sizeof(Notes)); // ប្លុកទី 2 ofile.write((char*)&Note3, sizeof(Notes)); .close(); // បិទឯកសារដែលបានកត់ត្រា ifstream ifile("Notebook.dat", ios::binary // រចនាសម្ព័ន្ធអថេរ char str; (!ifile.read((char*)&Note, sizeof(Notes)).eof())( sprintf(str, "%s\tPhone: %s\tAge: %d", Note.Name, Note.Phone, ចំណាំ.អាយុ);<< str << endl; } ifile.close(); // закрыть прочитанный файл cin.sync(); cin.get(); return 0; }

ជាលទ្ធផលនៃការប្រតិបត្តិកូដនេះ ឯកសារគោលពីរ Notebook.dat ត្រូវបានបង្កើតឡើងពីប្លុកបីនៃ 80 បៃនីមួយៗ (សន្មត់ថាតួអក្សរមានតែមួយបៃ)។ តាមធម្មជាតិ អ្នកអាចប្រើវិធីសាស្ត្រខ្សែស្រឡាយផ្សេងទៀត និងអនុវត្តប្រតិបត្តិការណាមួយនៅលើវាលនៃរចនាសម្ព័ន្ធទិន្នន័យជាក់លាក់មួយ។

ថ្នាក់ fstream៖ ការចូលប្រើឯកសារចៃដន្យ

ឧបមាថាយើងមាន 100 ធាតុនៅក្នុងសៀវភៅកត់ត្រារបស់យើង ហើយយើងចង់រាប់លេខ 50 ។ ជាការពិតណាស់អ្នកអាចរៀបចំរង្វិលជុំមួយហើយអានកំណត់ត្រាទាំងអស់ពីដំបូងទៅលេខដែលបានផ្តល់ឱ្យ។ ជាក់ស្តែងដំណោះស្រាយដែលមានគោលដៅជាងគឺកំណត់ទ្រនិចទីតាំងឯកសារ pos ដោយផ្ទាល់ទៅធាតុ 50 ហើយអានពីវា៖

ifstream ifile("Notebook.dat", ios::binary); int pos = 49 * sizeof(Notes); ifile.seekg(pos); // ស្វែងរកកំណត់ចំណាំទី 50;

// ចំណាំ – រចនាសម្ព័ន្ធ "កំណត់ត្រា" ដែលបានពិពណ៌នាខាងលើ ifile.read((char*)&Note, sizeof(Notes));

ប្រតិបត្តិការស្វែងរកបែបនេះមានប្រសិទ្ធភាពប្រសិនបើឯកសារមានកំណត់ត្រានៃទំហំដែលគេស្គាល់ និងថេរ។ ដើម្បីជំនួសមាតិកានៃកំណត់ត្រាបំពាន អ្នកត្រូវបើកស្ទ្រីមលទ្ធផលនៅក្នុងរបៀបកែប្រែ៖

Ofstream ofile ("Notebook.dat", ios::binary | ios::ate); int pos = 49 * sizeof(Notes); ofile seekp(pos); // ស្វែងរកធាតុទី 50 Notes Note50 = ("Yeltsin Boris Nikolaevich", "095-222-3322", 64); ofile.write((char*)&Note, sizeof(Notes)); // ការជំនួស

ជាចុងក្រោយ វាអាចបើកឯកសារក្នុងពេលដំណាលគ្នាសម្រាប់ការអាន/សរសេរ ដោយប្រើវិធីដែលទទួលមរតកដោយ fstream streaming class ពីអ្នកកាន់តំណែងមុនរបស់វា។ ដោយសារថ្នាក់ fstream គឺបានមកពី istream និង ostream (ឪពុកម្តាយរបស់ ifstream និង ofstream រៀងៗខ្លួន) វិធីសាស្ត្រទាំងអស់ដែលបានរៀបរាប់ពីមុនមាននៅក្នុងកម្មវិធី។

ឧទាហរណ៍ខាងក្រោមបង្ហាញពីការរៀបចំឡើងវិញនៃធាតុទីមួយ និងទីបីនៅក្នុងឯកសារ Notebook.dat ។

# រួមបញ្ចូល # រួមបញ្ចូល # រួមបញ្ចូល ដោយប្រើ namespace std; កំណត់ចំណាំរចនាសម្ព័ន្ធ (ឈ្មោះតួអក្សរ; ទូរស័ព្ទ char; int អាយុ; ); int main() ( setlocale(LC_ALL, "Russian"); Notes Note1, Note3; // បើកឯកសារសម្រាប់ការអាន/សរសេរក្នុងពេលដំណាលគ្នា fstream file("Notebook.dat", ios::binary | ios::in | ios: : ចេញ); file.seekg(2 * sizeof(Notes)); // find and read Note3 file.read((char*)&Note3, sizeof(Notes)); // find and read Note1 file.read((char *)&Note1, sizeof(Notes)); file.seekg(0);<== Note3 file.write((char*)&Note3, sizeof(Notes)); file.seekg(2 * sizeof(Notes)); // Note3 <== Note1 file.write((char*)&Note1, sizeof(Notes)); char str; // Считывать и отображать записи в цикле, пока не eof file.seekg(0); // вернуться к началу файла while (!file.read((char*)&Note1, sizeof(Notes)).eof()) { sprintf(str, "%s\tТел: %s\tВозраст: %d", Note1.Name, Note1.Phone, Note1.Age); cout << str << endl; } file.close(); cin.sync(); cin.get(); return 0; }

នៅក្នុង constructor នៃ file object អ្នកត្រូវតែបញ្ជាក់ ios::in and ios::out flags ដែលអនុញ្ញាតឱ្យដំណើរការអាន និងសរសេរក្នុងពេលដំណាលគ្នា។ ជាលទ្ធផលនៃការប្រតិបត្តិកូដនេះ ធាតុទីមួយ និងទីបីនៅក្នុងឯកសារគោលពីរ Notebook.dat នឹងត្រូវបានប្តូរ។

មានឧទាហរណ៍បន្ថែមលើប្រធានបទ។