bestimmte Zeile in Text Datei löschen
-
Hallo
Ich möchte eine Zeile aus einer TXT Datei löschen die zb
eine bestimmtes Wort enthält.Dabei sollen die restlichen zeilen nätürlich nachrücken, sodass keine Leerzeile entsteht.
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <conio.h> FILE *f; char buffer[256]; char test[50]; static int count; //fpos_t fpos; int main(void) { f = fopen("t.txt","r+"); if(f == NULL) { printf("Fehler beim Öffnen"); return EXIT_FAILURE; } while (fgets(buffer,sizeof(buffer),f) !=0) { count++; } fseek(f,0,0); for (int i=0;i<=count;i++) { fgets(buffer,sizeof(buffer),f); if (strstr(buffer,"Frosch")) { fgetpos(f,&fpos); printf("Text gefunden in Zeile %d\n",i+1); break; } } fclose(f); system("pause"); return 0; }
So weit bin ich
habe schon mit fseek und fg(s)etpos probiert->kein Erfolgvg Maxx175
-
Ich hab' Dir mal Deinen Code kommentiert:
#include <stdio.h> #include <string.h> #include <stdlib.h> /* #include <conio.h> nicht ANSI C... */ FILE *f; char buffer[256]; char test[50]; static int count; // static? Weißt du, was du hier tust? // ^^ globale Variablen sind ... meist unnötig. int main( void ) { f = fopen("t.txt","r+"); // Variablen benennen! if( f == NULL ) { printf( "Fehler beim Öffnen" ); return EXIT_FAILURE; } while( fgets( buffer, sizeof( buffer ), f ) != 0 ) { count++; } // du ließt immer wieder in den selben Speicher. // Zuletzt steht die letzte Zeile drin. fseek( f, 0, 0 ); // Der letzte Parameter muss einer aus SEEK_CUR, SEEK_END, SEEK_SET sein! for( int i = 0; i <= count; i++ ) // <= Operator? (Wennschon?) { fgets( buffer, sizeof( buffer ), f ); // Nochmal lesen?? if( strstr( buffer, "Frosch" ) ) { fgetpos( f, &fpos ); printf("Text gefunden in Zeile %d\n", i + 1 ); // reiner Zufallstreffer. break; } } fclose( f ); system( "pause" ); // unschön return 0; // unnötig }
Vielleicht teilst du das Gesamtproblem besser in Teile auf:
- Datei Zeilenweise einlesen
- Zu löschende Zeile suchen
- Zeile (im Speicher) löschen
- Datei zurückschreiben
- fertig
so zB:
#include <stdbool.h> /* bool */ #include <stddef.h> /* size_t */ #include <stdlib.h> #include <stdio.h> size_t count_lines( FILE *input_file ) { long initial_position; size_t num_lines = 1; char ch = 0; if( !input_file ) { return 0; } initial_position = ftell( input_file ); while( ( ch = fgetc( input_file ) ) != EOF ) { if( ch == '\n' ) { ++num_lines; } } fseek( input_file, initial_position, SEEK_SET ); return num_lines; } char* get_line( FILE *input_file ) { long initial_position = 0; size_t length = 0; char ch = 0, *buffer = 0; if( !input_file ) { return 0; } initial_position = ftell( input_file ); for( ch = fgetc( input_file ); ( ch != '\n' ) && ( ch != EOF ); ++length, ch = fgetc( input_file ) ); if( !length ) { buffer = calloc( 1, 1 ); return buffer; } fseek( input_file, initial_position, SEEK_SET ); buffer = malloc( length + 2 ); if( !buffer ) { return 0; } fgets( buffer, length + 1, input_file ); buffer[ length ] = 0; // assume Windows-Like "LF+CR", so skip two characters: fseek( input_file, 2, SEEK_CUR ); return buffer; } bool read_lines( char ***lines, size_t *num_lines, const char file_name[ ] ) { FILE *input_file = fopen( file_name, "r" ); size_t current_line = 0; if( !input_file ) { return false; } *lines = malloc( ( *num_lines = count_lines( input_file ) ) * sizeof( char* ) ); if( !( *lines ) ) { fclose( input_file ); return false; } for( ; current_line < *num_lines; ++current_line ) { ( *lines )[ current_line ] = get_line( input_file ); } fclose( input_file ); return true; } void delete_line( char ***lines, size_t *num_lines, size_t line_to_delete ) { size_t current_line = line_to_delete; if( num_lines <= line_to_delete ) { return; } free( ( *lines )[ line_to_delete ] ); for( ; current_line < ( *num_lines ) - 1; ++current_line ) { ( *lines )[ current_line ] = ( *lines )[ current_line + 1 ]; } ( *lines )[ --( *num_lines ) ] = 0; } bool write_lines( char **lines, size_t num_lines, const char file_name[ ] ) { FILE *output_file = fopen( file_name, "w+" ); size_t i = 0; if( !output_file ) { return false; } for( ; i < num_lines; ++i ) { fputs( lines[ i ], output_file ); fputc( '\r', output_file ); // windows... } fclose( output_file ); return true; } void free_lines( char **lines, size_t num_lines ) { size_t i = 0; for( ; i < num_lines; ++i ) { free( lines[ i ] ); } free( lines ); } int main( void ) { const char str_to_find[ ] = "another"; const char file_name[ ] = "test.txt"; char **lines = 0; size_t num_lines = 0, i = 0; bool found = false; if( !read_lines( &lines, &num_lines, file_name ) ) { fprintf( stderr, "File \"%s\" couldn't be opened!\n\n", file_name ); return EXIT_FAILURE; } for( ; i < num_lines; ++i ) { if( strstr( lines[ i ], str_to_find ) ) { printf( "\"%s\" found at line %u.\n", str_to_find, i + 1 ); found = true; break; } } if( found ) { delete_line( &lines, &num_lines, i ); if( !write_lines( lines, num_lines, file_name ) ) { fprintf( "\"%s\" couldn't be opened for writing!\n\n", file_name ); free_lines( lines, num_lines ); return EXIT_FAILURE; } printf( "\"%s\" written.\n\n", file_name ); } else { printf( "\"%s\" wasn't found in \"%s\".\nFile unchanged.\n\n", str_to_find, file_name ); } free_lines( lines, num_lines ); }
greetz, Swordfish
-
Und wenn deine read_lines den "Frosch" aufteilen?
Dann steht der Frosch am Ende immer noch drin, ne.Guckst du hier:
#define BUF 82 char* rem = "Frosch"; void filter( FILE* in, FILE* out ) { char* pstr = (rem+1); char buf[BUF]= {*rem}; int i = 1; while( *pstr && !feof(in) ) { if ( ! (buf[i++] = fgetc(in)) == *pstr++) break; } if ( *pstr ) fprintf(out, "%s", buf ); } int main(int argc, char *argv[]) { FILE* in, *out; int c; in = fopen("test.txt", "r"); out = fopen("test.tmp.txt", "w"); if ( !in || !out ) return 1; while( (c=fgetc(in)) != EOF ) { if(c == *rem ) filter(in, out); else fputc(c, out); } fclose(in); fclose(out); if ( remove("test.txt")) return 1; if ( rename("test.tmp.txt", "test.txt")); return 1; return 0; }
-
proggingmania schrieb:
Und wenn deine read_lines den "Frosch" aufteilen?
Dann steht der Frosch am Ende immer noch drin, ne.maxx175 schrieb:
Ich möchte eine Zeile aus einer TXT Datei löschen die zb
eine bestimmtes Wort enthält.Tja, ein
"Fro\nsch"
ist eben kein"Frosch"
... :pproggingmania schrieb:
Guckst du hier:
Guckst Du hier:
#include <stddef.h> #include <stdlib.h> #include <stdio.h> int main( void ) { const char file_name[ ] = "test.txt"; const char str_to_find[ ] = "Frosch"; const char *find_pos = str_to_find; char *buffer = 0, *tmp, *nl = 0; FILE *file = fopen( file_name, "r+" ); size_t buffer_size = 0; int ch; if( !file ) return EXIT_FAILURE; for( ch = fgetc( file ); ch != EOF; ch = fgetc( file ) ) { nl = ch == '\r' ? buffer + buffer_size : nl; if( ch == *find_pos && !find_pos[ 1 ] ) { if( nl ) { if( !( tmp = realloc( buffer, buffer_size = nl - buffer + 1 ) ) ) goto error_exit; buffer = tmp; } else { free( buffer ); buffer = buffer_size = 0; } find_pos = str_to_find; while( ( ch = fgetc( file ) ) != EOF && ch != '\r' ); continue; } else if( ch == *find_pos ) ++find_pos; else find_pos = str_to_find; if( !( tmp = realloc( buffer, ++buffer_size ) ) ) goto error_exit; ( buffer = tmp )[ buffer_size - 1 ] = ch; } if( ( file = freopen( file_name, "w", file ) ) ) fwrite( buffer, buffer_size, 1, file ); error_exit: free( buffer ); fclose( file ); }
Wird das jetzt ein "Ich schreib' den kürzeren, unlesbareren"-Contest?
greetz, Swordfish
-
Danke erstmals für die Posts
Aber keiner der Codes hat das gemacht was ich will:Geht das nicht ohne dass ich alle chars einzeln einlese.
Also:
TXT sieht so aus:
blablablabla juppijuppujuppi bla:Frosch sowiso sowiso
suche nach "Frosch"-> fgets; AAHHH -> gefunden in Zeile 2 (3)
Und jetzt lösche komplette Zeile "bla:Frosch" ->
neue TXT
blablablabla juppijuppujuppi sowiso sowiso
Zum meinem Code:
#include <stdio.h> #include <string.h> #include <stdlib.h> /* #include <conio.h> nicht ANSI C... */ //OK ist nur für Test (system("pause"); FILE *f; char buffer[256]; char test[50]; static int count; // static? Weißt du, was du hier tust? // ^^ globale Variablen sind ... meist unnötig. //OK muss noch viel lernen int main( void ) { f = fopen("t.txt","r+"); // Variablen benennen! //???const char file_name[ ] = "t.txt"; if( f == NULL ) { printf( "Fehler beim Öffnen" ); return EXIT_FAILURE; } while( fgets( buffer, sizeof( buffer ), f ) != 0 ) { count++; } // du ließt immer wieder in den selben Speicher. //Zuletzt steht die letzte Zeile drin. //macht ja nichts ;zähle ja nur die Zeilen!! fseek( f, 0, 0 ); // Der letzte Parameter muss einer aus SEEK_CUR, SEEK_END, SEEK_SET sein! // SEEK_SET (0) Beginning of file. // SEEK_CUR (1) Current position of the file pointer. // SEEK_END (2) End of file. for( int i = 0; i <= count; i++ ) // <= Operator? (Wennschon?) //?? nur = { fgets( buffer, sizeof( buffer ), f ); // Nochmal lesen?? //um den "Frosch zu suchen if( strstr( buffer, "Frosch" ) ) { fgetpos( f, &fpos );//TEST printf("Text gefunden in Zeile %d\n", i + 1 ); // reiner Zufallstreffer. //hat bei 10 verschiedenen TXTs-varianten 10 mal geklappt //wenn dass Zufall ist sollte ich einmal Lotto spielen :-) break; } } fclose( f ); system( "pause" ); // unschön //wie gesagt nur für TEST return 0; // unnötig //sonst mekert mein compi }
Also bei meinem Programm bleibt jetzt der Cursor in der nächsten Zeile( nach dem gefunden Wort) stehen.
Gibt es keine Anweisung um jetzt zu sagen, springe eine Zeile nach oben und lösche sie komplett? Dachte da an fsetpos,strncat und "\b"lg Maxx175
-
bist du sicher, das deine zeilen immer maximal 256 zeichen lang sind ?