2013-04-11 9 views
7

In C++ abbiamo un metodo per cercare il testo in un file. Funziona leggendo il file su una variabile e usando strstr. Ma ci siamo messi nei guai quando il file è diventato molto grande.Bug con find.exe?

Ho pensato di poter risolvere questo problema chiamando find.exe utilizzando _popen. Funziona trovare, a meno che queste condizioni sono tutte vere:

  • Il file è di tipo Unicode (BOM = FFFE)
  • Il file è esattamente 4096 byte
  • Il testo che si sta cercando è l'ultimo testo nel file

Per ricreare, si può fare questo:

  1. Aprire il Blocco note
  2. Inserire 2046 X di poi un A al termine
  3. Salva come test.txt, encoding = "unicode"
  4. Verificare che file è esattamente 4096 byte
  5. Aprire un prompt dei comandi e digitare: trovare "A"/c test2.txt -> No hits

ho provato anche questo:

  • aggiungere o eliminare un X, e si otterrà un successo (file è piú 4096 byte)
  • Salva come UTF-8 (e aggiungi abbastanza X in modo che il file sia nuovamente 4096 byte) e ottieni un successo
  • Cerca qualcosa nel mezzo del file (file ancora unicode e 4096 byte), e ottieni un colpo.

È un bug o c'è qualcosa che mi manca?

+2

Questo è interessante. Hai provato con altri multipli di 1024? O 4096? Cioè 8192 byte? –

+0

1024 e 2048 è ok, ma fallisce su 8192. –

+0

Wow - questo è un bug sgradevole :(Fallisce anche se la dimensione del file è di 8192 byte. Quando cerchi un personaggio nel mezzo, trova " linea ", ma si noti che manca l'ultimo carattere dall'output! Si ottiene X'es ma non A's – dbenham

risposta

4

Bug molto interessante.

Questa domanda mi ha indotto a fare alcuni esperimenti su XP e Win 7 - i comportamenti sono diversi.

XP

ANSI - TROVA non può leggere ultimi 1023 caratteri (1023 byte) su una sola riga. Trova può corrispondere a una riga che supera 1023 caratteri fino a quando la stringa di ricerca corrisponde prima del 1024. La stampa della linea corrispondente viene troncata dopo 1023 caratteri.

Unicode - FIND non può leggere oltre 1024 caratteri (2048 byte) su una singola riga. Trova può abbinare una linea che supera i 1024 caratteri fino a quando la stringa di ricerca corrisponde prima del 1025. La stampa della linea corrispondente viene troncata dopo 1024 caratteri.

Trovo molto strano che i limiti di riga per Unicode e ANSI su XP non siano lo stesso numero di byte, né è un multiplo semplice. Il limite Unicode espresso come byte è 2 volte il limite per ANSI più 1.

Nota: il troncamento delle linee lunghe uguali tronca anche il carattere di nuova riga, pertanto la riga successiva corrispondente verrà aggiunta alla riga precedente.Puoi dire che è una nuova riga se usi l'opzione/N.

Window 7

ANSI - non ho trovato un limite alla lunghezza della linea massima che può essere cercato, (anche se non ho provato molto duro). Qualsiasi linea corrispondente che supera i 4095 caratteri (4095 byte) viene troncata dopo 4095 caratteri. TROVA può cercare con successo oltre 4095 caratteri su una riga, ma non può visualizzarli tutti.

Unicode - Non ho trovato un limite alla lunghezza massima della linea che può essere cercata, (anche se non ho provato molto duramente). Qualsiasi riga corrispondente che supera i 2047 caratteri (4094 byte) viene troncata dopo 2047 caratteri. TROVA può cercare con successo oltre 2047 caratteri su una riga, ma non può visualizzarli tutti.

Poiché le lunghezze dei byte Unicode sono sempre un multiplo di 2 e la lunghezza massima visualizzabile ANSI è dispari, è logico che la lunghezza massima della linea visualizzabile in byte sia inferiore a Unicode rispetto a ANSI.

Ma poi c'è anche il bizzarro bug Unicode. Se la lunghezza del file Unicode è un multiplo esatto di 4096 byte, non è possibile cercare o stampare l'ultimo carattere. Non importa se il file contiene una singola riga o più righe. Dipende solo dalla lunghezza totale del file.

Trovo interessante il fatto che il multiplo del bug 4096 rientri nella lunghezza massima della linea stampabile (in byte). Ma non so se c'è una relazione tra quei comportamenti o se si tratta semplicemente di una coincidenza.

Nota: il troncamento delle linee lunghe uguali tronca anche qualsiasi carattere di nuova riga, pertanto la riga successiva corrispondente verrà aggiunta alla riga precedente. Puoi dire che è una nuova riga se usi l'opzione/N.

+0

Bug molto interessante! – Patashu

Problemi correlati