2010-11-17 25 views
6

J'essaie d'ouvrir un fichier et de le lire .. mais j'ai quelques problèmes.Ouvrir le fichier et lire à partir du fichier Objective-c

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

Ceci imprime: Test \ 377 \ 376N plutôt que n'importe quel contenu de mon fichier.

aucune idée pourquoi?

code complet:

#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; 

} 

Et le test242.txt ne contient pas plus de 200 caractères.

Répondre

13

Si ceci est pour Objective-C, pourquoi ne pas faire quelque chose comme:

utilisation 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 
} 

ou utiliser NSString:

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

ou si vous avez besoin de le lire ligne par ligne:

How to read data from NSFileHandle line by line?

OMI, il n'y a pas besoin de descendre au niveau C fonctions FileIO sauf si vous avez une très très bonne raison de le faire (par exemple, ouvrir un fichier en utilisant O_SHLOCK ou quelque chose)

+0

Le but est de lire le texte du fichier, mot par mot. Je suis nouveau à Objective-C, et (au moins si) je savais comment gérer les fichiers texte en utilisant les fonctions c. –

+2

Ceci est correct. Si le fichier ne contient pas nécessairement des données de chaîne (c'est-à-dire des octets bruts), utilisez un objet NSData avec son constructeur dataWithContentsOfFile et vous n'aurez pas à vous soucier de l'interprétation automatique des encodages de chaînes par NSString. –

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

Vous ne transmettez pas la chaîne à printf. Essayez

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

En outre, si votre fichier contient une ligne de plus de 200 caractères, fgets lira 200 caractères dans wah - puis ajoutez un NUL à la fin, qui sera l'extrémité de wah (depuis que vous avez déclaré il sera de 200 caractères) et piétinera quelque chose au hasard, et le comportement de votre programme sera indéfini et peut mettre le feu à votre chat.

+0

Je dois avoir fait ce bug en essayant de le réparer. J'ai édité pour être \t printf ("% s yeh \ n", wah); et il a le même problème –

+0

S'il vous plaît poster le code exact, complet, que vous testez. –

+0

Votre fichier existe-t-il? Vous ne vérifiez pas le succès de fopen –

3

Si vous ne me dérange pas lire tout d'un fichier que vous pouvez faire quelque chose comme ceci:

NSData* myData = [NSData dataWithContentsOfFile:myFileWithPath]; 

et faire tout ce que vous voulez avec les données à partir de là. Vous obtiendrez zéro si le fichier n'existe pas.

Si vous assumez le texte (string) données dans ce fichier, vous pouvez en outre faire quelque chose comme ça, et puis l'analyser comme NSString:

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

Puisque vous avez mentionné que vous êtes relativement nouveau à c objectif que vous peut chercher assez bien NSStrings. Jetez un oeil here pour plus d'informations à ce sujet.

+0

Je dois avoir fait ce bug en essayant de le réparer. J'ai édité pour être printf ("% s yeh \ n", wah); et il a le même problème –

+0

paul est correct, il y a peu de choses que nous pouvons faire sans plus d'informations. Êtes-vous sûr que votre fichier existe et que fgets lit les données? Essayez de placer wah à quelque chose d'abord pour vous assurer que la poubelle n'est pas juste des données non initialisées, comme ceci: char wah [200] = "hello"; – slycrel

+0

J'ai essayé d'initialiser wah à quelque chose, il imprime le test \ 377 \ 376H quand le programme s'exécute. Aussi, je vérifie maintenant, et le fichier existe définitivement. –

6

Votre fichier est stocké dans UTF-16 (Unicode). Le premier caractère de votre fichier est "L", qui est le point de code 0x4C. Les 4 premiers octets de votre fichier sont FF FE 4C 00, qui sont une marque d'ordre d'octet (BOM) et la lettre L codée en UTF-16 comme deux octets.

fgets n'est pas Unicode, donc il recherche le caractère de nouvelle ligne '\n', qui est l'octet 0x0A.Probablement cela se produira sur le premier octet d'une nouvelle ligne Unicode (les deux octets 0A 00), mais il pourrait aussi arriver sur beaucoup d'autres caractères non-nouvelle ligne tels que U + 010A (lettre majuscule latine A POINT PLUS HAUT) ou quoi que ce soit dans les scripts Gurmukhi ou Gujarati (U + 0A00 à U + 0AFF). En tout cas, cependant, les données qui finissent dans le tampon wah ont beaucoup de NULL incorporés et ressemblent à FF FE 4C 00 47 00 4F 00 4F 00 0A 00. NUL (0x00) est le terminateur de chaîne C, donc quand vous essayez d'imprimer ceci en utilisant printf, il s'arrête à la première null, et tout ce que vous voyez est \377\376L. \377\376 est la représentation octale des octets FF FE. La solution pour cela est de convertir votre fichier texte en un codage à un octet, tel que ISO 8859-1 ou UTF-8. Notez que les encodages codés sur un seul octet (excepté UTF-8) ne peuvent pas encoder toute la gamme des caractères Unicode, donc si vous avez besoin d'Unicode, je vous recommande fortement d'utiliser UTF-8. Vous pouvez également convertir votre programme en mode Unicode, mais vous ne pouvez plus utiliser beaucoup de fonctions de bibliothèque standard (telles que fgets et printf) et vous devez utiliser wchar_t partout à la place de char.

+0

... ou juste en utilisant quelque chose qui comprend nativement UTF16, comme 'NSString' –

+1

Ah Dave, vous enfants aujourd'hui avec des encodages de fantaisie, des cadres de haut niveau et maintenant même de la musique, vous allez ruiner notre beau monde .. . –

0

Slycrel l'a compris. Développant cette réponse, voici une autre (à mon avis, plus simple) moyen de transformer ces données en une chaîne:

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

Ceci déclare une nouvelle NSString en utilisant directement spécifié le NSData.

1

Je voulais cela aussi et je me suis dit "fais cela à la place" n'a pas répondu à la question, voici un exemple de travail ci-dessous. Méfiez-vous que fgets lit le délimiteur \ n et l'ajoute à votre texte.

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);