Προς το περιεχόμενο

διαγραφή γραμμών απο .ΤΧΤ


mpentenis

Προτεινόμενες αναρτήσεις

Δημοσ.

καλησπέρα

εχω ενα μικρό πρόβλημα με ενα αρχειο, το οποιο νομίζω οτι λύνεται με προγραμματισμό, αλλα δεν έχω ιδέα από τέτοια πράγματα...

θέλω μέσα σε ενα αρχειο .txt το οποιο δημιουργείται διαρκώς(εκτυπωση απο εμπορική εφαρμογή) να μένουν οι 10 πρώτες γραμμές, και ότι υπάρχει απο εκεί και κάτω να διαγράφεται.το αρχειο ορισμένες φορές έχει μόνο τις 10 γραμμες, (συνεπως είναι σωστό), άλλες φορές έχει 21 γραμμές (10 σωστές, μια κενή και 10 ακόμα άλλες)

 

 

πως μπορεί να γίνει κάτι τέτοιο?μόνο σε ενα .txt θέλω να επέμβω, το οποιο δεν είναι read-only, ούτε θα χρισιμοποιείται απο άλλη εφαρμογή.το προγραμματακι αυτο 8α χρησιμοποιηθει για να εκτελεσει αργοτερα ενα αλλο .bat, συνεπως σκεφτομαι κάτι με εντολες dos σε μορφή .bat

Δημοσ.

Γινεται σε οποιαδήποτε γλώσσα. με εντολες dos πιθανόν, αλλα θα ηταν η τελευταία μου επιλογή.

 

Eχω κατι παρόμοιο σε κώδικα Autoit, αλλα δεν ειναι dos. το μηχανημα πρεπει να τρέχει windows, αλλα δεν χρειαζεται το Autoit εγκατεστημένο.

Autoit ειναι εδώ, δωρεάν, http://www.autoitscript.com/autoit3/downloads.php

το θελει μονο αυτος που θα γραψει το script και θα το κανει .exe

 

αν ενδιαφέρει, reply

Δημοσ.

C :

>
#include <stdio.h>

#define myfile "example.txt" // change this if needed
#define fixedfile "fixed.txt" // change this if needed


int main() {

FILE *fp;
FILE *fp2;
int c;
int newlines = 10; // change this if needed

if(!(fp = fopen(myfile, "rb"))) {
	fprintf(stderr, "Error: Unable to open %s for reading.\n", myfile);
	return 1;
}

if(!(fp2 = fopen(fixedfile, "w"))) {
	fprintf(stderr, "Error: Unable to open %s for writting.\n", fixedfile);
	fclose(fp);
	return 2;
}

while((c = getc(fp)) != EOF && newlines) {
	if(c == '\n')
		--newlines;
	fputc(c, fp2);
}

fclose(fp);
fclose(fp2);

}

Δημοσ.

ευχαριστώ και τουσ 2 για τις απαντησεις σας.δεν ξερω κατα ποσο με καλυπτουν αυτα (γιατι δεν ξερω καν απο προγραμματισμο οπως προανεφερα)

θα σας δωσω μια συντομη περιγραφη της διαδικασιας, για να μου πειτε να κανει

η εμπορικη εφαρμογη δημιουργει ενα αρχειακι, το οποιο μετατρεπει σε .txt, και στην συνεχεια εκτελει ενα .bat για να στειλει το .τχτ στην lpt1

 

αυτο λοιπον που θελώ να κάνω είναι, μόλις δημιουργείται το .τχτ, να τρεχει το δικό μου πρόγραμμα (χωρις να επεμβαίνει ο χρήστης), να αφαιρεί τις γραμμες, και στην συνέχεια να εκτελεί το .bat που στέλνει στην θύρα

Δημοσ.
C :

>
#include <stdio.h>

#define myfile "example.txt" // change this if needed
#define fixedfile "fixed.txt" // change this if needed


int main() {

FILE *fp;
FILE *fp2;
int c;
int newlines = 10; // change this if needed

if(!(fp = fopen(myfile, "rb"))) {
	fprintf(stderr, "Error: Unable to open %s for reading.\n", myfile);
	return 1;
}

if(!(fp2 = fopen(fixedfile, "w"))) {
	fprintf(stderr, "Error: Unable to open %s for writting.\n", fixedfile);
	fclose(fp);
	return 2;
}

while((c = getc(fp)) != EOF && newlines) {
	if(c == '\n')
		--newlines;
	fputc(c, fp2);
}

fclose(fp);
fclose(fp2);

}

 

 

Gia poio logo anhgeis to arxeio me binary flag?

 

@mpentenis

 

Katebase to programma DevC++ kai kane compile ton parapano kwdika me tis ekshs allages:

 

int main(int argc, char *argv[]) {

 

if(!(fp = fopen(argv[1], "r"))) {

 

if(!(fp2 = fopen(argv[2], "w"))) {

 

Afou to kaneis compile 8a pareis ena executable. Ean to trekseis me 2 parametrous (palio arxeio h 1h parametros kai to neo arxeio me tis 10 grammes h 2h) 8a pareis to neo arxeio pou 8eleis

 

GL

Δημοσ.
ευχαριστώ και τουσ 2 για τις απαντησεις σας.δεν ξερω κατα ποσο με καλυπτουν αυτα (γιατι δεν ξερω καν απο προγραμματισμο οπως προανεφερα)

θα σας δωσω μια συντομη περιγραφη της διαδικασιας, για να μου πειτε να κανει

η εμπορικη εφαρμογη δημιουργει ενα αρχειακι, το οποιο μετατρεπει σε .txt, και στην συνεχεια εκτελει ενα .bat για να στειλει το .τχτ στην lpt1

 

αυτο λοιπον που θελώ να κάνω είναι, μόλις δημιουργείται το .τχτ, να τρεχει το δικό μου πρόγραμμα (χωρις να επεμβαίνει ο χρήστης), να αφαιρεί τις γραμμες, και στην συνέχεια να εκτελεί το .bat που στέλνει στην θύρα

 

Σε linux αυτο που ζητάς είναι μια γραμμή (head -n 10 > newtext.txt).

Σε windows , εφοσον δεν ξέρεις απο προγραμματισμό , δεν έχεις άλλη επιλογή απο το να αγοράσεις ενα πρόγραμμα που κανει job automation.

Μπορείς να κατεβάσεις minigw tools, και να τρεξεις την head, η Μπορείς να γράψεις vb script. Either way, θα μπλέξεις περισσότερο.

Δημοσ.
αυτο λοιπον που θελώ να κάνω είναι, μόλις δημιουργείται το .τχτ, να τρεχει το δικό μου πρόγραμμα (χωρις να επεμβαίνει ο χρήστης), να αφαιρεί τις γραμμες, και στην συνέχεια να εκτελεί το .bat που στέλνει στην θύρα

 

αυτη η δευτερη απαιτηση ειναι το μπλέξιμο.

ειχα φτιαξει ενα σκριπτ για κατι παρόμοιο, και το εβαλα να τρεχει σαν service, καθε Χ λεπτά,

εστω, Α το προγραμμα δημιουργιας, Β το σκριπτ που κοβει τις 10 γραμμες, Γ το προγραμμα που στελνει στη θυρα,

 

αλλα δεν ηταν σωστό, γιατι μερικές φορές ξεκίναγε το Β, πριν τελειώσει το Α, και έμπλεκε το συμπαν.

 

για να παιξει, πρεπει να επέμβεις στο .bat το Γ, για να τρέξει το Β, και να περιμένει να τελειώσει, πριν συνεχίσει.

 

 

 

ο κωδικας σε Autoit

>
; chop10.au3
; What it does:
; OPENS A FILE NAMED "a.txt" (variable $f)
; COUNTS LINES
; IF LINES <= 10 (variable $max) DO NOTHING. displays a message, you can comment it.
; IF MORE THAN 10,
; CREATE A BACKUP COPY OF THE FILE (can comment it)
; AND SAVE THE FIRST 10 LINES TO A NEW FILE WITH THE SAME NAME (a.txt)

; REQUIREMENTS: Windows and Autoit3 ( http://www.autoitscript.com/autoit3/downloads.php )

#NoTrayIcon
#include <File.au3>
$max=10
$f="a.txt"
$cnt=0
$cnt= _FileCountLines($F)

if $cnt <= $max then
   Msgbox(0, "", "Nothing to do. File has only "& $cnt & " lines")
   exit
endif

Dim $Ar[$max]

$file=FileOpen($f,0)
; Check if file opened for reading OK
If $file = -1 Then
   MsgBox(0, "Error", "Unable to open file "& $f " for Read")
   Exit
EndIf

$cnt=0
While 1
   $line = FileReadLine($file)
   If @error = -1 Then ExitLoop
   if $cnt<$max then
       $Ar[$cnt]= $line
   endif
   $cnt=$cnt+1
WEnd
Fileclose($f)

FileCopy( $f, $f & ".BAK.TXT" , 1 ) ;KEEP A BACKUP
   $f2=FileOpen( $f  ,2) ;WRITE OVER OLD FILE
   If $f2= -1 Then
           MsgBox(0, "Error", "Unable to open file "& $f " for Write")
           Exit
   endif

   For $i = 0 to $max-1 ;WRITE FIRST LINES OF OLD TO NEW
   $w = FileWriteLine($f2, $Ar[$i] )
   If $w=0 Then
           MsgBox(0, "Error", "Unable to write line "& $i+1 &" into file "& $f)
           Exit
   endif
   Next
Fileclose($f2)

 

1. εγκαθιστας το autoit

2. save τον κωδικα ως chop10.au3 (στο φακελο που βρισκεται το a.txt)

3. με διπλο κλικ εκτελειται, τεσταρεις

4. οταν μεινεις ευχαριστημενος, κανεις δεξι κλικ στο au3, και "compile script", δημιουργει chop10.exe,

5. τροποποιείς το .bat να καλει το .exe με την εντολη

START /WAIT chop10.exe

 

 

 

μπορεις να αλλαξεις μερικα πράγματα, οπως

$max=10 --γραμμες που θελεις να κρατησεις

$f="a.txt" --ονομα αρχειου προς επεξεργασια

 

σβηνεις το FileCopy( $f, $f & ".BAK.TXT" , 1 ) αν δεν χρειάζεσαι αντιγραφο του παλιού -χρησιμο για τα πρωτα τεστ.

 

και σβηνεις το Msgbox(0, "", "Nothing to do. File has only "& $cnt & " lines") αν δεν θελεις μηνυμα οταν το προγραμμα δεν κανει τίποτα, επειδη το a.txt ειναι <=10 γραμμες.

Δημοσ.

Άν σπουδάζαμε στο Dalhousie University στον Καναδά στο CSCI 2132:Software Development θα είχαμε σίγουρα δει -και πιθανότατα λύσει- αυτό το θέμα: (12/50 marks είναι καλά? είναι το 5ο και δυσκολότερο θέμα)

 

5) Write a C program similar to the standard unix head program. (12 marks)

 

/* Compile gcc -g head.c -o head

* Run: head [ -<num> ] file ...

* where <num> is the number of lines to print (default is 10)

* eg head -15 f1 f2 f3 f4

* prints the first 15 lines (or what there is) of each file

* the -<num> may appear anywhere among the arguments but at most once

* e.g. head f1 f2 -15 f3 f4 gives same result

* When more than one file is specified, each file is preceded by:

==> filename <== and there will be a blank line between file outputs

* with no file arguments reads from stdin and does not print ==> filename <==

*/

#include <stdio.h> // fopen, fclose, fgets, fputs, BUFSIZ, stdin, stdout

#include <stdlib.h> // atoi

 

Αν το λύσει κάποιος, ας βάλει και το εκτελέσιμο (σε DOS?) ώστε να κάνει την δουλειά του ο φίλος mpentenis.

Δημοσ.

profanos giayto asxoli8ika me ta texnika kai oxi ta epaggelmatika :P

peritto na sas pw oti apo ta misa apo osa grapsate, katalaba...oute ta misa :P

sas eyxaristw pantws, argotera poy 8a teleiwsw tis douleies moy, 8a dokimasw ka8e me8odo, kai 8a sas pw ta apotelesmata (an den kanei mpam :P)

Δημοσ.
Άν σπουδάζαμε στο Dalhousie University στον Καναδά στο CSCI 2132:Software Development θα είχαμε σίγουρα δει -και πιθανότατα λύσει- αυτό το θέμα: (12/50 marks είναι καλά? είναι το 5ο και δυσκολότερο θέμα)

 

5) Write a C program similar to the standard unix head program. (12 marks)

 

/* Compile gcc -g head.c -o head

* Run: head [ -<num> ] file ...

* where <num> is the number of lines to print (default is 10)

* eg head -15 f1 f2 f3 f4

* prints the first 15 lines (or what there is) of each file

* the -<num> may appear anywhere among the arguments but at most once

* e.g. head f1 f2 -15 f3 f4 gives same result

* When more than one file is specified, each file is preceded by:

==> filename <== and there will be a blank line between file outputs

* with no file arguments reads from stdin and does not print ==> filename <==

*/

#include <stdio.h> // fopen, fclose, fgets, fputs, BUFSIZ, stdin, stdout

#include <stdlib.h> // atoi

 

Αν το λύσει κάποιος, ας βάλει και το εκτελέσιμο (σε DOS?) ώστε να κάνει την δουλειά του ο φίλος mpentenis.

 

Θα μπορούσε να γίνει έτσι:

 

>
/*---------------------------------------------------------------------------
  Echo up to line number Utility R3.
  Copyright (C) XD Feb 2007

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
  USA.


  Compile notice:
  ===============
   If Borland C/C++ Builder 6.0 user, compile this software with wildargs.obj
   (refer to C/C++ Builder Lib directory) to enable argc/argv automatic
   wildcards handling.

   Developed in 32bit were C INT is considerated as a 32bit DWORD with MAXINT
   equal to 2,147,483,647 (LONG) instead of 16bit INT were equal to 32,767
   (SHORT INT in C/C++ Builder 6.0).
-----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <values.h> // R2

#ifdef __BORLANDC__
  #pragma hdrstop
#endif

/*---------------------------------------------------------------------------*/
#define  _DEFAULT_MAX_LINE 15
/*---------------------------------------------------------------------------*/
int   _PrintLine(char *pszFilename,int nLine);
/*---------------------------------------------------------------------------*/

#ifdef __BORLANDC__
  #pragma argsused
#endif
int main(int argc, char* argv[])
{
  int   nArgcIdx, nMaxLine = _DEFAULT_MAX_LINE, nCIdx;
  char  *pszNum = NULL, cUseHeader = 0;

  // Parameters processing
  for(nArgcIdx=1;nArgcIdx<argc;nArgcIdx++)
   {
     if(argv[nArgcIdx][0]=='?')
      {
        printf("|HEAD or \"Echo up to line number\" Utility R3.");
        printf("|Copyright 2007 by Directx.\n\n");
        printf(" Usage: HEAD -number file ...\n");
        return -1;
      }

     if(argv[nArgcIdx][0]=='-')
      {
        if(pszNum!=NULL)
         {
           printf(" Please define -<num> once (%s)!\n",argv[nArgcIdx]);
           return -1;
         }
        else
         pszNum = argv[nArgcIdx];

        if(strlen(argv[nArgcIdx])>1)
         {
           for(nCIdx=1;nCIdx<(int)strlen(argv[nArgcIdx]);nCIdx++)
            if(!isdigit(argv[nArgcIdx][nCIdx]))
             {
               printf(" Please define only numbers in -<num> (%s)!\n",argv[nArgcIdx]);
               return -1;
             }

           // R3 - Stop on nMaxLine overflow (>MAXINT then nMaxLine becomes negative)
           if((nMaxLine = atoi(&argv[nArgcIdx][1]))<0)
            {
              printf(" Syntax Error:-<num> out of range!\n");
              return -1;
            }
         }
        else
         {
           printf(" Invalid -<num> defined!\n");
           return -1;
         }
      }
   }

  // Any files defined? if no echo stdin up to nMaxLine
  if((pszNum!=NULL && argc-1==1) || (argc==1))
   _PrintLine(NULL,nMaxLine);
  else
   {
     // R2 - Bug fix (to avoid minor bug in -num interpretation)
     if(argc>2)
      cUseHeader = (pszNum!=NULL && argc-1<=2)?0:1;

     // Print File Lines
     for(nArgcIdx=1;nArgcIdx<argc;nArgcIdx++)
      {
        // R2 - Reorganized condition (to avoid continue;)
        if(argv[nArgcIdx]!=pszNum)
         {
           if(cUseHeader)
            printf(" ==> %s <==\n",argv[nArgcIdx]);

           if(_PrintLine(argv[nArgcIdx],nMaxLine)==-1)
            printf(" DOS Error: Cannot open file for read - %s\n",argv[nArgcIdx]);
         }
      }
   }

  return 0;
}
/*---------------------------------------------------------------------------*/
int   _PrintLine(char *pszFilename,int nLine)
{
  // Print file or stdin (if pszFilename==NULL) up to nLines
  FILE  *Stream;
  int   nChar,nLineCount = 0;

  if((Stream=(pszFilename!=NULL)?fopen(pszFilename,"rb"):stdin)!=NULL)
   {
     while((nChar=fgetc(Stream))!=EOF && nLineCount<nLine)
      {
        if(nChar=='\n')
         nLineCount++;
        putchar(nChar);
      }
     fclose(Stream);
   }
  else
   nLine = -1;

  return nLine;
}

 

Ο τρόπος που υλοποιεί την υπόδειξη αλλαγή γραμμής (\n) η C διαφέρει μεταξύ DOS/Windows και Unix, καθώς τα πρώτα υλοποιούν το \n ως \r\n ενώ το δεύτερο ως \n υπονοώντας το \r. Στο δε MacOS προ του X η αλλαγή γραμμής αντιστοιχούσε σε \r !!

Φυσικά οι βιβλιοθήκες κάθε compiler για DOS/Windows ή Unix προσαρμόζουν αυτομάτως τον τρόπο διαχείρισης της C ντιρεκτίβας \n οπότε το πρόβλημα γίνεται εντελώς διάφανο για τον προγραμματιστή.

 

Ο κώδικας γράφτηκε σχετικά γρήγορα σε Borland C/C++ Builder 6.0 οπότε μπορεί να περιέχει bugs συνεπώς προσοχή.

 

Καλή συνέχεια.

 

Υ.Γ.

Πρόσθεσα ένα συνημμένο zip με το εκτελέσιμο για Windows Console 32bit, το C Source, μερικές οδηγίες χρήσης και την άδεια χρήσης GPL 2.

Ελπίζω να φανεί χρήσιμο.

 

Μπορείτε επίσης, να οδηγήσετε την έξοδο της εφαρμογής σε ένα νέο αρχείο με την χρήση του τελεστή >, έτσι η εντολή headc test.txt -5 > new.txt θα δημιουργήσει ένα νέο αρχείο (new.txt) με τις 5 πρώτες γραμμές του αρχείου test.txt

headcR3.zip

Δημοσ.

Έχεις δίκιο δεν μου πέρασε καθόλου από το μυαλό, ύστερα δεν την σκέφτηκα καθώς θέλει ορισμό μεγέθους του προς ανάγνωση stream -βέβαια μπορείς να ορίσεις ένα μεγάλο buffer θα μου πεις, αλλά τι γίνεται αν έχουμε μια συνεχόμενη γραμμή μεγαλύτερη από αυτό; ..

 

==

 

Ακολουθεί η εκδοχή της fgets με την προϋπόθεση πως το ανώτατο μέγεθος μιας γραμμής είναι για παράδειγμα 4kbs.

 

>
int   _PrintLine(char *pszFilename,int nLine)
{
  // Print file or stdin (if pszFilename==NULL) up to nLines
  FILE  *Stream;
  char  szBuffer[4096] = "";

  if((Stream=(pszFilename!=NULL)?fopen(pszFilename,"rb"):stdin)!=NULL)
   {
     while(fgets(szBuffer,_MAX_LINE_LEN,Stream)!=NULL && nLine--)
      printf("%s",szBuffer);

     fclose(Stream);
     return 0;
   }
  return -1;
}

Δημοσ.
Σε linux αυτο που ζητάς είναι μια γραμμή (head -n 10 > newtext.txt).

Σε windows , εφοσον δεν ξέρεις απο προγραμματισμό , δεν έχεις άλλη επιλογή απο το να αγοράσεις ενα πρόγραμμα που κανει job automation.

Μπορείς να κατεβάσεις minigw tools, και να τρεξεις την head, η Μπορείς να γράψεις vb script. Either way, θα μπλέξεις περισσότερο.

 

Και στα windows γινεται με batch file. Δυστυχως δεν ειναι τοσο κομψο οσο σε linux

 

>
@echo off

set /a count=0
For /F %%f In (oldfile.txt) Do call :linecopy %%f 
goto :end


:linecopy
set /a count=%count%+1
if %count% LEQ 10 echo %1 >> newfile.txt 
goto :eof


:end
del oldfile.txt
ren newfile.txt oldfile.txt
pause

 

Μπακαλικο και inefficient αλλα δουλευει

Το pause δεν χρειαζεται, πρεπει αν το βγαλεις αμα τελικα το χρησιμοποιησεις.

Σε αυτο το σημειο μπορεις να καλεσεις με call το αλλο bat που στελνει το κειμενο για εκτυπωση. Αν μας γραψεις τα περιεχομενα το bat αυτου θα πρεπει να μπορουμε να το γραψουμε ολο σε ενα αρχειο και να το αντικαταστησουμε τελειως

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...