2010-11-17 3 views
6

Sto tentando di aprire un file e di leggerlo .. ma sto riscontrando alcuni problemi.Apri il file e leggi dal file Obiettivo-c

FILE *libFile = fopen("/Users/pineapple/Desktop/finalproj/test242.txt","r"); 
char wah[200]; 
fgets(wah, 200, libFile); 
printf("%s test\n", wah); 

questa stampa: \ 377 \ 376N test piuttosto che uno qualsiasi dei contenuti del mio file.

qualche idea del perché?

codice completo:

#import <Cocoa/Cocoa.h> 
#import <stdio.h> 

int main(int argc, char *argv[]) 
{ 
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 

FILE *libFile = fopen("/Users/pineapple/Desktop/finalproj/test242.txt","r"); 
if(libFile){ 
char wah[200]; 
fgets(wah, 200, libFile); 
printf("%s test\n", wah); 
    } 
[pool drain]; 
return 0; 

} 

E la test242.txt non contiene più di 200 caratteri.

risposta

13

Se questo è per Objective-C, perché non fare qualcosa di simile:

uso NSFileHandle:

NSString * path = @"/Users/pineapple/Desktop/finalproj/test242.txt"; 
NSFileHandle * fileHandle = [NSFileHandle fileHandleForReadingAtPath:path]; 
NSData * buffer = nil; 
while ((buffer = [fileHandle readDataOfLength:1024])) { 
    //do something with the buffer 
} 

o utilizzare NSString:

NSString * fileContents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; 

o se avete bisogno di leggerlo riga per riga:

How to read data from NSFileHandle line by line?

IMO, non c'è bisogno di discesa al livello C funzioni FileIO a meno che non si dispone di un molto molto molto buona ragione per farlo (ad esempio, aprire un file utilizzando O_SHLOCK o qualcosa)

+0

L'obiettivo è leggere il testo dal file, parola per parola. Sono nuovo di Objective-C, e (almeno se) sapevo come gestire i file di testo usando le funzioni c. –

+2

Questo è corretto. Se il file non contiene necessariamente dati stringa (cioè byte non elaborati), utilizza un oggetto NSData con il relativo costruttore dataWithContentsOfFile e non dovrai preoccuparti dell'interpretazione automatica di NSString delle stringhe di stringhe. –

0
printf("%s test\n"); 

Non stai passando la stringa a printf. Prova

printf("%s test\n", wah); 

Inoltre, se il file contiene una linea lunga più di 200 caratteri, fgets leggeranno 200 caratteri in wah - quindi aggiungere un NUL fino alla fine, che sarà l'estremità del wah (poiché dichiarato deve essere di 200 caratteri) e calpesterà qualcosa di casuale, e il comportamento del tuo programma sarà indefinito e potrebbe dare fuoco al tuo gatto.

+0

Devo aver creato questo errore durante il tentativo di risolvere il problema. Ho modificato per essere \t printf ("% s yeh \ n", wah); e ha lo stesso problema –

+0

Inserisci il codice esatto, completo, che stai testando. –

+0

Il tuo file esiste? Non stai controllando il successo di fopen –

3

Se non ti dispiace aver letto tutto di un file che si può fare qualcosa di simile:

NSData* myData = [NSData dataWithContentsOfFile:myFileWithPath]; 

e poi fare tutto ciò che vuoi con i dati da lì. Otterrai zero se il file non esiste.

Se si stanno assumendo il testo (stringa) i dati in questo file è possibile inoltre fare una cosa del genere e quindi analizzare come un NSString:

NSString* myString = [[NSString alloc] initWithBytes:[myData bytes] length:[myData length] encoding:NSUTF8StringEncoding]; 

Dal momento che lei ha citato sono relativamente nuovi per Objective-C si può cercare NSStrings abbastanza bene. Date un'occhiata a here per maggiori informazioni su questo.

+0

Devo aver creato questo bug mentre cercavo di risolverlo. Ho modificato per essere printf ("% s yeh \ n", wah); e ha lo stesso problema –

+0

paul è corretto, c'è poco che possiamo fare senza ulteriori informazioni. Sei sicuro che il tuo file esista e che Fgets stia leggendo i dati? Prova a impostare wah su qualcosa prima per assicurarti che la spazzatura non sia solo dati non inizializzati, qualcosa del genere: char wah [200] = "ciao"; – slycrel

+0

Ho provato a inizializzare wah su qualcosa, stampa il test \ 377 \ 376H quando il programma è in esecuzione. Inoltre, sto verificando e il file esiste sicuramente. –

6

Il file viene memorizzato in UTF-16 (Unicode). Il primo carattere nel tuo file è "L", che è il punto di codice 0x4C. I primi 4 byte del file sono FF FE 4C 00, che sono un contrassegno di ordine dei byte (BOM) e la lettera L codificata in UTF-16 come due byte.

fgets non è compatibile con Unicode, quindi sta cercando il carattere di nuova riga '\n', che è il byte 0x0A.Molto probabilmente ciò avverrà sul primo byte di una nuova riga Unicode (i due byte 0A 00), ma potrebbe verificarsi anche su molti altri caratteri non di nuova riga come U + 010A (LETTER CAPITAL LETTER A WITH DOT ABOVE) o qualsiasi cosa in gli script Gurmukhi o Gujarati (da U + 0A00 a U + 0AFF).

In ogni caso, tuttavia, i dati che finiscono nel buffer wah hanno molti null incorporati e assomigliano a FF FE 4C 00 47 00 4F 00 4F 00 0A 00. NUL (0x00) è il terminatore di stringa C, quindi quando si tenta di stampare questo utilizzando printf, si arresta al primo null e tutto ciò che viene visualizzato è \377\376L. \377\376 è la rappresentazione ottale dei byte FF FE.

La correzione per questo è per convertire il file di testo in una codifica a byte singolo come ISO 8859-1 o UTF-8. Nota che le codifiche a byte singolo (escluso UTF-8) non possono codificare l'intero intervallo di caratteri Unicode, quindi se hai bisogno di Unicode, ti consiglio vivamente di utilizzare UTF-8. In alternativa, è possibile convertire il programma in modalità Unicode, ma in questo caso non è più possibile utilizzare molte funzioni di libreria standard (come fgets e printf) ed è necessario utilizzare wchar_t ovunque al posto di char.

+0

... o semplicemente usando qualcosa che comprenda UTF16 in modo nativo, come 'NSString' –

+1

Ah Dave, voi ragazzi oggi con codifiche elaborate, quadri di alto livello e ora anche battere musica, state per rovinare il nostro bel mondo .. . –

0

Slycrel ce l'ha. Ampliando la risposta, ecco un altro (a mio parere, più semplice) modo di trasformare i dati in una stringa:

NSString *myFileString = [[NSString alloc] initWithData:someData encoding:NSUTF8StringEncoding]; 

Questo dichiara una nuova NSString direttamente utilizzando il NSData specificato.

1

Volevo anche questo e ho pensato "fai questo invece" non ha risposto alla domanda, ecco un esempio di lavoro qui sotto. Fai attenzione che Fgets legge il delimitatore \ n e aggiunge al tuo testo.

NSString * fName = [[NSBundle mainBundle] pathForResource:@"Sample" ofType:@"txt"]; 
FILE *fileHandle = fopen([fName UTF8String],"r"); 
char space[1024]; 
while (fgets(space, 1024, fileHandle) != NULL) 
{ 
    NSLog(@"space = %s", space); 
} 

fclose(fileHandle);