CFArrayGetValueAtIndex not returning aything - objective-c

I have an extremely simple code snippet to get the application support directory of a use. Problem is, it doesn't work! I get the values in a CFArrayRef (because I want to use C code since I will use this snippet in a C++ application later) and try to get the first string in there using CFArrayGetValueAtIndex(). I convert the returned void* to a char* using a C-style cast and attempt to output it using printf(), but nothing gets outputted! Can anyone explain why? I've looked online through the documentation for CFArray and tried to google the issue, but came up with nothing. Any help would be really appreciated!
Code:
#include <Foundation/Foundation.h>
#include <typeinfo>
int main (int argc, const char * argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
CFArrayRef array = \
(CFArrayRef)NSSearchPathForDirectoriesInDomains(
NSApplicationSupportDirectory,
NSUserDirectory,
YES);
char* string = (char*)CFArrayGetValueAtIndex(array, 0);
printf("string: %s\n", string);
[pool drain];
}

Why are you converting it to a char*? The resulting array from NSSearchPathForDirectoriesInDomains() contains CFStringRefs, not char*s.
Try using CFShow((CFTypeRef)CFArrayGetValueAtIndex(array, 0));

Related

simple code with EXC_BAD_ACCESS

I am new to the objective c and i write the code according to a reference book.
but something went wrong and I don't know why.
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
if (argc==1){
NSLog(#"you need to provide a file name");
return (1);
}
FILE *wordFile = fopen(argv[1], "r");
char word[100];
while(fgets(word , 100, wordFile)){
word[strlen(word)-1] = '\0';
NSLog(#"the length of the %s is %lu", word, strlen(word));
}
fclose(wordFile);
return 0;
}
the tool indicates that the while part went wrong, EXC_BAD_ACCESS.
Any idea?
It compiles and runs fine on my machine. But imagine you have an empty line in your file. Then strlen(word) will return zero. Hence word[strlen(word)-1] = '\0'; will try to set some memory which might not be valid since word[-1] might not be a valid memory cell, or a memory cell that you can legally access.
Oh, and by the way, it has nothing to do with objective-c. This is mostly (but for the NSLog call) pure ansi C.

Objective-C, Simple String input from Console?

I honestly did a) search using key words and b) read the 'questions with similar titles' before asking this.
Also I tried to make this question more concise, but I had a hard time doing that in this case. If you feel the question is too wordy, I get it. Just don't try to answer.
I'm trying to write very simple objective-C programs that mirror the basic assignments in my introductory java class. I worked through an objective-c book over the summer and now I want to do lots of practice problems in objective-c, at the same time as I do java practice problems. I'm avoiding the objective-c GUI environment and just want to focus on working with the language for awhile. I still have a lot to learn about how to figure things out.
The program I'm duplicating from my java homework, is a standard type. I ask the user for number input and string input via the console. I was able to get numeric input from the console using an example I found here using scan f. (I will put the couple code lines below). But I'm unsure on how to get console input and store it in a string (NSString). I'm trying to learn to use the apple documentation and found a reference to a scan type command, but I cannot figure out how to USE the command. The one that seems likely is
scanCharactersFromSet:(NSCharacterSet )scanSet intoString:(NSString *)name;
Here's what I understand and works
int age = 0;
NSLog (#"How old are y'all?");
scanf("%d", &age);
NSLog (#"\n Wow, you are %d !", age);
But I don't understand how to pickup an NSString called 'name'. I THINK I'm supposed to make my 'name'a pointer, because the class is NSString.
(BTW I did try using scanf to pickup the string, but the compiler doesn't like me trying to use scanf in conjunction with name. It says that I shouldn't be using 'scanf' because it's expecting a different kind of data. I'm not sure where I found the data type 'i'. I was looking through my text for different ideas. I'm guessing that scanf is related to 'scanfloat' which clearly deals with numeric data, so this is not a big surprise)
I realize that 'scanf' isn't the right command (and I don't really get why I can't even find scanf in the apple documentation - maybe it's C?)
I'm guessing that scanCharactersFromSet might be the right thing to use, but I just don't understand how you figure out what goes where in the command. I guess I tend to learn by example, and I haven't found an example. I'd like to figure out how to learn properly by reading the documentation. But I'm not there yet.
NSString* name ;
scanf("%i", &name);
//scanCharactersFromSet:(NSCharacterSet *)scanSet intoString:(NSString **)name;
...
My book is oriented towards moving me into a gui environment, so it doesn't deal with input.
Thank you for any pointers you can give me.
Laurel
I would recommend ramping up on C. Objective-c is a thin layer over C and that knowledge will pay for itself over and over.
There's multiple ways in C to read:
http://www.ehow.com/how_2086237_read-string-c.html
For example:
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
char str[50] = {0}; // init all to 0
printf("Enter you Last name: ");
scanf("%s", str); // read and format into the str buffer
printf("Your name is %s\n", str); // print buffer
// you can create an NS foundation NSString object from the str buffer
NSString *lastName = [NSString stringWithUTF8String:str];
// %# calls description o object - in NSString case, prints the string
NSLog(#"lastName=%#", lastName);
[pool drain];
return 0;
NOTE: the simple scanf is succeptible to buffer overruns. There's multiple approaches around this. see:
How to prevent scanf causing a buffer overflow in C?
Here is what Objective C looks like:
NSString *FNgetInput() {
#autoreleasepool {
return [[[NSString alloc] initWithData:[[NSFileHandle fileHandleWithStandardInput] availableData] encoding:NSUTF8StringEncoding] stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
}
}
The way to get data from the standard input (or any other file handle) in cocoa is to use the NSFileHandle class. Check the docs for +fileHandleWithStandardInput
Here's how to get user input using Objective-C in 2020:
main.m
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
#autoreleasepool {
// insert code here...
NSLog(#"Hello, World!");
char str[50] = {0}; // init all to 0
printf("Enter you Last name: ");
scanf("%s", str); // read and format into the str buffer
printf("Your name is %s\n", str); // print buffer
// you can create an NS foundation NSString object from the str buffer
NSString *lastName = [NSString stringWithUTF8String:str];
// %# calls description o object - in NSString case, prints the string
NSLog(#"lastName=%#", lastName);
return 0;
}
return 0;
}
Compile and run:
$ clang -framework Foundation main.m -o app

getting errors using macros in Objective-C

I am new to Objective-C. I was trying out a sample program using macros and getting errors.
#import <Foundation/Foundation.h>
#define HELLO_WORLD #"Hello World"
#define a(x,y) ((x)+(y))
#define PRINTMAC(x,y)\
NSLog(#"%d",a((x),(y));\
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// insert code here...
//NSLog(#"%d",add(10,20));
PRINTMAC(13,72); //error:
[pool drain];
return 0;
} //error:
Error: expected ';' before '}' token
You appear to be missing a ) on the NSLog line (line 8).
Additionally, I'm not sure you need the final \ on that line, as the macro is not being carried on to a third line.
Finally, I don't think you need the ; on that line either as it, combined with the semi-colon when you invoke the macro on line 15 results in an empty statement (shouldn't be harmful, though).

CLANG Pass-By-Value Warning?

The following code compiles fine ...
int main (int argc, const char * argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// VARIABLES
MDD *MDD_structure;
NSString *mddFile = #"/Users/Gary/Code/Mdd/xTest.mdd";
NSFileHandle *inFile;
NSData *inBuffer;
int MDD_fCount;
int MDD_vCount;
// OPEN FILE ON DISK
inFile = [NSFileHandle fileHandleForReadingAtPath:mddFile];
if(inFile == nil) NSLog(#"FILE: Open ... ERROR");
else NSLog(#"FILE: Open ... OK");
// READ FRAME COUNT
inBuffer = [inFile readDataOfLength:sizeof(int)];
[inBuffer getBytes:&MDD_fCount length:sizeof(int)];
MDD_fCount = CFSwapInt32BigToHost(MDD_fCount);
NSLog(#"FC: %d", MDD_fCount);
But when I run it through the static analyzer "CLANG LLVM 1.0" I get the following ...
warning: Pass-by-value argument in function call is undefined.
MDD_fCount = CFSwapInt32BigToHost(MDD_fCount);
^ ~~~~~~~~~~
1 diagnostic generated.
Can anyone tell me what I am missing?
gary
You're getting an error because clang isn't convinced that simply passing the address of your variable to a function is the same as giving it a value. You could probably initialize MDD_fCount to 0 to start with to get rid of the error.
It means that you haven't initialized MDD_fCount. See this blog post and this other question for additional info.

Very basic Objective-C/C Problem

Here's my code:
#import <Foundation/Foundation.h>
void PrintPathInfo() {
const char *path = [#"~" fileSystemRepresentation];
NSLog(#"My home folder is at '%#'", path);
}
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
PrintPathInfo();
[pool drain];
return 0;
}
And here's my problem:
Program received signal: “EXC_BAD_ACCESS”.
I really think the problem is my NSLog but I don't know how to solve it.
Could someone help me please? Thanks!
path is not an NSString, which is why that crashes. %# in a formatting string expects an object, and asks it for a description to get a string to print... because you are using a C style string, you need to use the standard C string formatters OR convert the const char * back to an NSString using the initWithCString:encoding: class method of NSString.
Staying with a const char *, you can use:
NSLog(#"My home folder is at '%s'", path);
which would work.
%# is for objects. (Like NSString). for const char* you will want the good old %s from the c's printf format codes.
See http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html
For the format specifies and their meanings