mpentenis Δημοσ. 12 Φεβρουαρίου 2007 Δημοσ. 12 Φεβρουαρίου 2007 καλησπέρα εχω ενα μικρό πρόβλημα με ενα αρχειο, το οποιο νομίζω οτι λύνεται με προγραμματισμό, αλλα δεν έχω ιδέα από τέτοια πράγματα... θέλω μέσα σε ενα αρχειο .txt το οποιο δημιουργείται διαρκώς(εκτυπωση απο εμπορική εφαρμογή) να μένουν οι 10 πρώτες γραμμές, και ότι υπάρχει απο εκεί και κάτω να διαγράφεται.το αρχειο ορισμένες φορές έχει μόνο τις 10 γραμμες, (συνεπως είναι σωστό), άλλες φορές έχει 21 γραμμές (10 σωστές, μια κενή και 10 ακόμα άλλες) πως μπορεί να γίνει κάτι τέτοιο?μόνο σε ενα .txt θέλω να επέμβω, το οποιο δεν είναι read-only, ούτε θα χρισιμοποιείται απο άλλη εφαρμογή.το προγραμματακι αυτο 8α χρησιμοποιηθει για να εκτελεσει αργοτερα ενα αλλο .bat, συνεπως σκεφτομαι κάτι με εντολες dos σε μορφή .bat
random Δημοσ. 13 Φεβρουαρίου 2007 Δημοσ. 13 Φεβρουαρίου 2007 Γινεται σε οποιαδήποτε γλώσσα. με εντολες dos πιθανόν, αλλα θα ηταν η τελευταία μου επιλογή. Eχω κατι παρόμοιο σε κώδικα Autoit, αλλα δεν ειναι dos. το μηχανημα πρεπει να τρέχει windows, αλλα δεν χρειαζεται το Autoit εγκατεστημένο. Autoit ειναι εδώ, δωρεάν, http://www.autoitscript.com/autoit3/downloads.php το θελει μονο αυτος που θα γραψει το script και θα το κανει .exe αν ενδιαφέρει, reply
phr0z Δημοσ. 13 Φεβρουαρίου 2007 Δημοσ. 13 Φεβρουαρίου 2007 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); }
mpentenis Δημοσ. 13 Φεβρουαρίου 2007 Μέλος Δημοσ. 13 Φεβρουαρίου 2007 ευχαριστώ και τουσ 2 για τις απαντησεις σας.δεν ξερω κατα ποσο με καλυπτουν αυτα (γιατι δεν ξερω καν απο προγραμματισμο οπως προανεφερα) θα σας δωσω μια συντομη περιγραφη της διαδικασιας, για να μου πειτε να κανει η εμπορικη εφαρμογη δημιουργει ενα αρχειακι, το οποιο μετατρεπει σε .txt, και στην συνεχεια εκτελει ενα .bat για να στειλει το .τχτ στην lpt1 αυτο λοιπον που θελώ να κάνω είναι, μόλις δημιουργείται το .τχτ, να τρεχει το δικό μου πρόγραμμα (χωρις να επεμβαίνει ο χρήστης), να αφαιρεί τις γραμμες, και στην συνέχεια να εκτελεί το .bat που στέλνει στην θύρα
Επισκέπτης Δημοσ. 13 Φεβρουαρίου 2007 Δημοσ. 13 Φεβρουαρίου 2007 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
bandito Δημοσ. 13 Φεβρουαρίου 2007 Δημοσ. 13 Φεβρουαρίου 2007 ευχαριστώ και τουσ 2 για τις απαντησεις σας.δεν ξερω κατα ποσο με καλυπτουν αυτα (γιατι δεν ξερω καν απο προγραμματισμο οπως προανεφερα)θα σας δωσω μια συντομη περιγραφη της διαδικασιας, για να μου πειτε να κανει η εμπορικη εφαρμογη δημιουργει ενα αρχειακι, το οποιο μετατρεπει σε .txt, και στην συνεχεια εκτελει ενα .bat για να στειλει το .τχτ στην lpt1 αυτο λοιπον που θελώ να κάνω είναι, μόλις δημιουργείται το .τχτ, να τρεχει το δικό μου πρόγραμμα (χωρις να επεμβαίνει ο χρήστης), να αφαιρεί τις γραμμες, και στην συνέχεια να εκτελεί το .bat που στέλνει στην θύρα Σε linux αυτο που ζητάς είναι μια γραμμή (head -n 10 > newtext.txt). Σε windows , εφοσον δεν ξέρεις απο προγραμματισμό , δεν έχεις άλλη επιλογή απο το να αγοράσεις ενα πρόγραμμα που κανει job automation. Μπορείς να κατεβάσεις minigw tools, και να τρεξεις την head, η Μπορείς να γράψεις vb script. Either way, θα μπλέξεις περισσότερο.
random Δημοσ. 13 Φεβρουαρίου 2007 Δημοσ. 13 Φεβρουαρίου 2007 αυτο λοιπον που θελώ να κάνω είναι, μόλις δημιουργείται το .τχτ, να τρεχει το δικό μου πρόγραμμα (χωρις να επεμβαίνει ο χρήστης), να αφαιρεί τις γραμμες, και στην συνέχεια να εκτελεί το .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 γραμμες.
Eusebius Δημοσ. 13 Φεβρουαρίου 2007 Δημοσ. 13 Φεβρουαρίου 2007 > ssed 10q test-lines.txt >test-lines-new.txt Φαίνεται να δουλεύει καλά σε XP, και με κείμενο UTF-8 και με ANSI. http://sed.sourceforge.net/grabbag/ssed/ (44kB) http://sed.sourceforge.net/sed1line.txt < κλεμμένο από δω ΥΓ. Δοκίμαζα και δεν είδα το ποστ του random.
chiossif Δημοσ. 13 Φεβρουαρίου 2007 Δημοσ. 13 Φεβρουαρίου 2007 Άν σπουδάζαμε στο 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.
Επισκέπτης Δημοσ. 13 Φεβρουαρίου 2007 Δημοσ. 13 Φεβρουαρίου 2007 Syntax: copyfile.exe oldfile newfile
mpentenis Δημοσ. 13 Φεβρουαρίου 2007 Μέλος Δημοσ. 13 Φεβρουαρίου 2007 profanos giayto asxoli8ika me ta texnika kai oxi ta epaggelmatika peritto na sas pw oti apo ta misa apo osa grapsate, katalaba...oute ta misa sas eyxaristw pantws, argotera poy 8a teleiwsw tis douleies moy, 8a dokimasw ka8e me8odo, kai 8a sas pw ta apotelesmata (an den kanei mpam )
Directx Δημοσ. 13 Φεβρουαρίου 2007 Δημοσ. 13 Φεβρουαρίου 2007 Άν σπουδάζαμε στο 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
chiossif Δημοσ. 13 Φεβρουαρίου 2007 Δημοσ. 13 Φεβρουαρίου 2007 @directX: Bravo! Τι θά'λεγες για χρήση της fgets να γλιτώνεις; Επίσης καλός ο έλεγχος σφαλμάτων.
Directx Δημοσ. 13 Φεβρουαρίου 2007 Δημοσ. 13 Φεβρουαρίου 2007 Έχεις δίκιο δεν μου πέρασε καθόλου από το μυαλό, ύστερα δεν την σκέφτηκα καθώς θέλει ορισμό μεγέθους του προς ανάγνωση 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; }
Bspus Δημοσ. 14 Φεβρουαρίου 2007 Δημοσ. 14 Φεβρουαρίου 2007 Σε 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 αυτου θα πρεπει να μπορουμε να το γραψουμε ολο σε ενα αρχειο και να το αντικαταστησουμε τελειως
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.