There are two subroutines in the code: а and b . Each subroutine must work with the same file. Accordingly, depending on the function called, the positioning in the file should change. How to do it right? Is the fseek function suitable here? Is it possible to change the positioning directly in rows?

Here is the code:

 #define _CRT_SECURE_NO_WARNINGS #define _CRT_NONSTDC_NO_WARNINGS #include <stdio.h> #include <conio.h> #include <locale> #include <string.h> FILE* fOpenForReadSavely(const char* filename) {//открывает файл для чтения, если он есть, или создает новый FILE *file; file = fopen(filename, "r"); if (file == NULL) { fclose(file); file = fopen(filename, "w"); fclose(file); file = fopen(filename, "r"); } return file; } FILE* fOpenForWriteSavely(const char* filename) {//открывает файл для записи, если он есть, или создает новый FILE *file; file = fopen(filename, "r+"); if (file == NULL) { fclose(file); file = fopen(filename, "w"); fclose(file); file = fopen(filename, "r+"); } return file; } void printMin() { FILE *file = fOpenForReadSavely("io.txt"); char buffer[100]; fseek(file, 8, SEEK_END); fgets(buffer, 100, file); //printf("\nmin = %d", min); puts(buffer); fclose(file); } void printm() { char buffer[100]; FILE *file = fOpenForReadSavely("io.txt"); fgets(buffer, 100, file); puts(buffer); fclose(file); } void findMin() { FILE *file = fOpenForReadSavely("io.txt"); int min = INT32_MAX; int m[20]; char buffer[100],*element; fseek(file, 0, SEEK_SET); fgets(buffer, 100, file); element = strtok(buffer, " "); for (int i = 1; i < 20; i++) { m[i] = (int)element; element = strtok(NULL, " "); } for (int i = 0; i < 20; i++) { if (m[i] < min && m[i]) min = m[i]; } fseek(file, 0, SEEK_END); fprintf(file, "\n min = %2d", min); fclose(file); } void generateM(int m[], char *filename) { srand(time(NULL)); FILE *file = fOpenForWriteSavely(filename); fseek(file, 0, SEEK_SET); for (int i = 0; i < 20; i++) { m[i] = rand() % 32; fprintf(file, "%2d ", m[i]); } //fprintf(file, "\n"); fclose(file); } void printmm() { FILE *file = fOpenForReadSavely("io.txt"); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { //printf("%2d ", m[i][j]); } printf("\n"); } fclose(file); } void printNearEquals() { FILE *file = fOpenForReadSavely("io.txt"); //printf("count = %d", count); fclose(file); } void findNearEquals() { FILE *file = fOpenForReadSavely("io.txt"); int count = 0; for (int i = 0; i < 9; i++) { for (int j = 0; j < 10; j++) { //if (m[i][j] == m[i][j + 1]) count++; } } fclose(file); } void generateMM(int **m) { FILE *file = fOpenForWriteSavely("io.txt"); srand(time(NULL)); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { m[i][j] = rand() % 32; } } fclose(file); } char* getFileName() { char * filename; scanf("%s", &filename); if (strstr(filename, ".txt") == NULL) { strcat(".txt", filename); } return filename; } void a() { int m[20]; int* p = m; char *filename; printf("Введите имя файла: "); filename = getFileName(); generateM(p, filename); printm(); findMin(); printMin(); } void b() { int** m; m = new int*[10]; for (int i = 0; i < 10; i++) m[i] = new int[10]; generateMM(m); printmm(); findNearEquals(); printNearEquals(); for (int i = 0; i < 10; i++) delete[] m[i]; delete[] m; } int main() { setlocale(LC_ALL, "Russian"); printf("Задание а или б: "); char c = getchar(); if (c == 'a' | c == 'а') { a(); } else if (c == 'b' | c == 'б') { b(); } else if (c != 'a' | c != 'b' | c != 'а' | c != 'б') { printf("\nerror"); getch(); } getch(); } 
  • Positioning capabilities are very different for binary and text files. You open files in text mode. In text files, there is no arbitrary positioning at all, except for the possibility to make fseek to the position previously returned by ftell . - AnT

1 answer 1

About positioning in text files you have already written in the comment - @AnT . However, your fseek calls put the position in the file only at the beginning or the end, and everything will work fine (in the sense of setting the pointer where it is necessary, because MS says : the search works correctly with offset 0 relative to any origin value ). In addition to one call - about him further:

 fseek(file, 8, SEEK_END); 

Here you are trying to go beyond the file - 8 bytes further than it ends. This is not prohibited in principle (see ibid. ), But empty spaces will be filled with zeros. Is this exactly the behavior you want?

 if (file == NULL) { fclose(file); 

Do not close a file that is not open . This is what the documentation says:

The fclose function closes stream. If the stream parameter is NULL, the invalid parameter handler is invoked, as described in the Check Parameters section. If execution can continue, fclose sets errno to EINVAL and returns EOF. It is recommended that you always check the stream pointer before calling this function.

  file = fopen(filename, "w"); fclose(file); file = fopen(filename, "r"); 

Here you create an empty file and open it for reading. What can be read from it?

  file = fopen(filename, "w"); fclose(file); file = fopen(filename, "r+"); 

An empty file is created here, then opened for writing and reading. But the same can be expressed in one call -

  file = fopen(filename, "w+"); 

(see here ).