Prologue:
At @avp, the solution is much better, but if for some reason you need some more complicated mediation with the text, writing them, for example, in char** , you can see my solution.
There are no functions, all in one, so you can not figure it out.
Let's just write it on the ANSI standard :)
A few notes:
- few comments, because it would be redundant: D;
- I tried to validate everything carefully, so the code seems large;
- preprocessor directives - at the end.
main itself:
/*gcc -o main ...*/ /*./main input_file output_file*/ int main(int argc, char const *argv[]) { if ( 3 != argc ) return -1; if ( 0 != write_reverse_from( argv[1], argv[2] ) ) { fprintf(stderr,"Writing has been failed!\n"); return -2; } return 0; }
All the most interesting is in write_reverse_from (tried to write as much as possible, in my understanding, "pure", so that you could understand):
int write_reverse_from ( const char* file_in_name, const char* file_out_name ) { FILE* fp_input; FILE* fp_output; char** input_content; uint32_t lines_count; char** output_content; fp_input = fopen( file_in_name, "r" ); fp_output = fopen( file_out_name, "w" ); if ( NULL == fp_input ) return -1; if ( NULL == fp_output ) return -2; /*ΠΏΠΎΠ»ΡΡΠΈΡΡ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΡΡΠΎΠΊ Π² ΡΠ°ΠΉΠ»Π΅*/ lines_count = get_lines_count_from( fp_input ); if ( 0 == lines_count ) return -3; /*ΠΏΠΎΠ»ΡΡΠΈΡΡ ΠΊΠΎΠ½ΡΠ΅Π½Ρ Π² Π²ΠΈΠ΄Π΅ ΠΌΠ°ΡΡΠΈΠ²Π° ΡΡΡΠΎΠΊ*/ input_content = get_input_content( fp_input, lines_count ); /*Π·Π°ΠΊΡΡΠ²Π°Π΅ΠΌ ΡΠ°ΠΉΠ»ΠΎΠ²ΡΠΉ ΠΏΠΎΡΠΎΠΊ ΠΈΡΡ
ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°. ΠΠΎΠ»ΡΡΠ΅ Π½Π΅ Π½ΡΠΆΠ΅Π½*/ fclose( fp_input ); if ( NULL == input_content ) { fclose( fp_output ); return -4; } /*ΠΏΠΎΠ»ΡΡΠΈΡΡ "ΠΏΠ΅ΡΠ΅Π²ΡΡΠ½ΡΡΡΠΉ" ΠΌΠ°ΡΡΠΈΠ² ΡΡΡΠΎΠΊ*/ output_content = get_reversed_content_from( input_content, lines_count ); if ( NULL == output_content ) { free_content( input_content, lines_count ); fclose( fp_output ); return -5; } /*Π·Π°ΠΏΠΈΡΠ°ΡΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π² ΠΈΡΠΎΠ³ΠΎΠ²ΡΠΉ ΡΠ°ΠΉΠ»*/ print_content_to( fp_output, output_content, lines_count ); /*Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΏΠ°ΠΌΡΡΠΈ content-ΠΎΠ²*/ free_content( input_content, lines_count ); free_content( output_content, lines_count ); fclose( fp_output ); return 0; }
I am showing now the implementation in order.
The function get_lines_count_from just "goes over" in a standard way (not feof way, please note: D) through the file, "winding" a simple counter:
static uint32_t get_lines_count_from ( FILE* opened_fp ) { uint32_t lines_count = 0L; char line[ MAX_LINE_SIZE ]; if ( NULL == opened_fp ) return 0; fseek( opened_fp, 0L, SEEK_SET ); /* ΡΠ΅ΡΠ΅Π½ΠΈΡ Ρ feof Π»ΡΡΡΠ΅ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ */ while ( NULL != fgets( line, MAX_LINE_SIZE, opened_fp ) ) lines_count++; return lines_count; }
Here is how I take the contents of the input file:
static char** get_input_content ( FILE* opened_fp, uint32_t lines_count ) { char line[ MAX_LINE_SIZE ] = {0}; char** content; uint32_t alloc_counter = 0L; if ( NULL == opened_fp || 0L == lines_count ) return NULL; content = malloc( sizeof( char** ) * lines_count ); while( alloc_counter < lines_count ) { content[alloc_counter] = malloc( sizeof(char*) * MAX_LINE_SIZE ); alloc_counter++; } alloc_counter = 0L; fseek( opened_fp, 0L, SEEK_SET ); while( NULL != fgets( line, MAX_LINE_SIZE, opened_fp ) ) { strcpy( content[alloc_counter], line ); memset( line, 0, MAX_LINE_SIZE); alloc_counter++; } return content; }
Here it is "turning":
static char** get_reversed_content_from( char** content, uint32_t lines_count ) { uint32_t alloc_counter = 0L; char* last_content_line; char** reversed_content; if ( NULL == content || 0L == lines_count ) return NULL; last_content_line = content[ lines_count - 1UL ]; if ( NULL == strchr( last_content_line, '\n' ) ) /*Π΅ΡΠ»ΠΈ Π² ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅ΠΉ ΡΡΡΠΎΠΊΠ΅ Π½Π΅Ρ ΡΠΈΠΌΠ²ΠΎΠ»Π° Π½ΠΎΠ²ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ*/ { if ( MAX_LINE_SIZE - 1UL <= strlen( last_content_line ) ) return NULL; strcat( last_content_line, LINE_END ); /*ΡΠΈΠΌΠ²ΠΎΠ» NUL ΠΏΠΎΡΠ»Π΅ ΡΡΠΎΠ³ΠΎ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ Π½Π΅ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ ΠΏΡΠΈ ΡΡΠ΅Π½ΠΈΠΈ Ρ Π½Π°Ρ ΠΈΡΠ½ΠΎΡΠΌΠ°ΡΠΈΡ Π·Π°Π½ΠΎΡΠΈΠ»Π°ΡΡ Π² Π·Π°ΡΠ°Π½Π΅Π΅ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ Π½ΡΠ»ΡΠΌΠΈ ΠΌΠ°ΡΡΠΈΠ², ΠΈ ΡΠΎΠ»ΡΠΊΠΎ ΠΏΠΎΡΠΎΠΌ Π±ΡΠ»ΠΎ ΠΏΠ΅ΡΠ΅ΠΌΠ΅ΡΠ΅Π½ΠΈΠ΅ Π² Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΡΡ ΠΏΠ°ΠΌΡΡΡ (Π½Π°ΠΉΠ΄ΠΈΡΠ΅ ΡΡΡΠΎΡΠΊΡ Ρ memset)*/ } reversed_content = malloc( sizeof( char** ) * lines_count ); while( alloc_counter < lines_count ) { reversed_content[alloc_counter] = malloc( sizeof(char*) * MAX_LINE_SIZE ); strcpy(reversed_content[alloc_counter], content[lines_count - 1U - alloc_counter]); alloc_counter++; } return reversed_content; }
Output to the final file:
static int print_content_to( FILE* opened_fp, char** content, uint32_t lines_count) { uint32_t lines_counter = 0; if ( NULL == opened_fp || NULL == content || 0L == lines_count ) return -1; while( lines_counter < lines_count ) { fprintf(opened_fp, "%s", content[lines_counter]); lines_counter++; } return 0; }
The very release of variables of type char** :
static void free_content( char** content, uint32_t lines_count) { uint32_t lines_counter = 0; if ( NULL == content || 0 == lines_count ) return; while ( lines_counter < lines_count ) { free(content[lines_counter]); lines_counter++; } free(content); }
Well, the promised directives:
#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #define MAX_LINE_SIZE ( 1024UL ) #ifdef _WIN32 #define LINE_END "\r\n" #else #define LINE_END "\n" #endif
newis no longer C :) - Harrystrcpy_s(mas[i], 300, buf);The second parameter is incorrect. The size of the buffer allocated formas[i]is not at all 300. Well, the fidelity of theiindex itself is also in doubt. - VTT