Hi,
I'm new to Objective C but I have previous experience with C++.
After creating a couple of simple programs to get used to the new syntax, I decided to embark in something just a little more complex.
I'm coding a program that encrypts a .txt file with a user-inputted password. I have already done this program in C++ under windows in the past, now I'm trying to make it for mac (altho I lost the old C++ version). For now I'm just trying to make it copy the .txt file into a new .txt file, without using the simple FileManager method because I'll eventually want to mess(encrypt) with the read buffer before writing to the new file.
well here's the code, i added comments to make it clear what im doing
class interface: TxtCrypt.h
implementation: (TxtCrypt.mm)
main.mm:
you read it thru here, so thanks in advance.
first, am I doing it the way it's supposed to be done in objective c? e.g. the .h file, the two .mm files, the way im implementing the methods, is it correct objective c style?
now the real problem:
when i run, it goes fine until this part:
i get this crash in the console:
i don't understand what's wrong with my call initwithcontentsoffile.
Also, I get several warnings in the following lines like:
NSData may not respond to method +initwithcontentsoffile. Isn't it a "normal" method of NSData?
also, when i do stuff like
the output of filename is a memory address instead of the string associated with filename. any help here?
any help is appreciated.
I'm new to Objective C but I have previous experience with C++.
After creating a couple of simple programs to get used to the new syntax, I decided to embark in something just a little more complex.
I'm coding a program that encrypts a .txt file with a user-inputted password. I have already done this program in C++ under windows in the past, now I'm trying to make it for mac (altho I lost the old C++ version). For now I'm just trying to make it copy the .txt file into a new .txt file, without using the simple FileManager method because I'll eventually want to mess(encrypt) with the read buffer before writing to the new file.
well here's the code, i added comments to make it clear what im doing
class interface: TxtCrypt.h
Code:
/*
* TxtCrypt.h
* TxtCrypt
*
* Created by Edo on 11/14/10.
* Copyright 2010 __MyCompanyName__. All rights reserved.
*
*/
// extend NSString to copy input from "cin >>" and return it as NSString
@interface NSString (readFromCin)
-(NSString*) readFromCin;
@end
@interface TxtCrypt : NSObject
{
}
-(NSString*) askFileName: (bool) forInput; // asks file name for input files, or asks file name and creates file for output
-(int) askPin: (bool) forDecrypt; // asks pin to decrypt file, or (new) pin to encrypt file
-(bool) encrypt;
-(bool) decrypt;
@end
implementation: (TxtCrypt.mm)
Code:
/*
* encrypt.h
* TxtCrypt
*
* Created by Edo on 11/14/10.
* Copyright 2010 __MyCompanyName__. All rights reserved.
*
*/
#import <Foundation/Foundation.h>
#import <stdlib.h>
#import <iostream>
#import "TxtCrypt.h"
using namespace std;
// extend NSString to copy input from "cin >>" and return it as NSString
@implementation NSString (readFromCin)
-(NSString*) readFromCin {
string buff;
cin >> buff;
NSString* name = [[NSString stringWithUTF8String:buff.c_str()] retain];
return name;
}
@end
@implementation TxtCrypt
-(NSString*) askFileName: (bool) forInput {
bool ok = false;
NSString* filename = [[NSString alloc] init];
NSFileManager *unique = [NSFileManager defaultManager];
// ask name of a file to read from
if(forInput) {
cout << "Enter input file name, including extention: ";
while (ok == false) {
[filename readFromCin];
if ([unique fileExistsAtPath: @"file.txt"] == YES) { //im using @"file.txt" because i had problems identifying the file. it should however be filename. i created file.txt in the directory so it finds it"
cout << endl << "File " << filename << " successfully opened." << endl;
ok = true;
}
else
cout << "File " << filename << " does not exist. Please enter correct name: ";
}
}
// ask name and create a file to write to
else {
cout << "Enter output file name, including desired extention: ";
while (ok == false) {
[filename readFromCin];
if ([unique fileExistsAtPath: filename] == NO) {
[unique createFileAtPath:filename contents:nil attributes:nil];
cout << endl << "File " << filename << " successfully created." << endl;
ok = true;
}
else
cout << "File " << filename << " already exists. Please enter different name: ";
}
}
return filename;
}
-(int) askPin: (bool) forDecrypt {
int pin;
if (forDecrypt) {
cout << "Please enter correct pin number for decypt: ";
cin >> pin;
}
else {
cout << "Please enter desired pin number for encryption: ";
cin >> pin;
}
cout << endl;
return pin;
}
-(bool) encrypt {
NSString* inputFileName;
NSString* outputFileName;
// NSFileHandle* inputFile;
NSFileHandle* outputFile;
NSData* readBuffer;
NSData* writeBuffer = [NSData data];
NSRange* range;
int pin;
// ask file to encrypt; ask output file. initialize NSFileHandle. ask new pin to encrypt
inputFileName = [self askFileName:true];
assert(inputFileName != nil);
outputFileName = [self askFileName:false];
assert(outputFileName != nil);
outputFile = [NSFileHandle fileHandleForWritingAtPath:outputFileName];
pin = [self askPin:false];
// read entire input file to buffer. apply encryption to buffer. write buffer to output.
readBuffer = [NSData initWithContentsOfFile:inputFileName];
for (int i = 0; i <= sizeof([readBuffer lenght]); i++) {
[range NSMakeRange:i:1];
[readBuffer getBytes:writeBuffer:range];
[outputFile seekToEndOfFile];
[outputFile writeData:writeBuffer];
}
[outputFile closeFile];
return true;
}
@end
main.mm:
Code:
#import <Foundation/Foundation.h>
#import "TxtCrypt.h"
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
id session = [[TxtCrypt alloc] init];
NSLog (@"Current directory is %@", currentpath);
[session encrypt];
[pool drain];
return 0;
}
you read it thru here, so thanks in advance.
first, am I doing it the way it's supposed to be done in objective c? e.g. the .h file, the two .mm files, the way im implementing the methods, is it correct objective c style?
now the real problem:
when i run, it goes fine until this part:
Code:
readBuffer = [NSData initWithContentsOfFile:inputFileName];
for (int i = 0; i <= sizeof([readBuffer lenght]); i++) {
[range NSMakeRange:i:1];
[readBuffer getBytes:writeBuffer:range];
[outputFile seekToEndOfFile];
[outputFile writeData:writeBuffer];
}
i get this crash in the console:
Code:
2010-11-14 13:37:39.598 TxtCrypt[1881:80f] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSData initWithContentsOfFile:]: unrecognized selector sent to class 0xa075702c'
*** Call stack at first throw:
(
0 CoreFoundation 0x95ee6bba __raiseError + 410
1 libobjc.A.dylib 0x93524509 objc_exception_throw + 56
2 CoreFoundation 0x95f3399b +[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x95e8d7e6 ___forwarding___ + 950
4 CoreFoundation 0x95e8d3b2 _CF_forwarding_prep_0 + 50
5 TxtCrypt 0x0000252e -[TxtCrypt encrypt] + 347
6 TxtCrypt 0x00002867 main + 232
7 TxtCrypt 0x00001f9d start + 53
)
Also, I get several warnings in the following lines like:
NSData may not respond to method +initwithcontentsoffile. Isn't it a "normal" method of NSData?
also, when i do stuff like
Code:
cout << endl << "File " << filename << " successfully created." << endl;
any help is appreciated.