I'm working with another programmer on some code. He has written a decoding algorithm in C, and provided me with an Objective-c class the serves as a wrapper to avoid me to have to handle calls to his code.
His .h file looks like this
#import <UIKit/UIKit.h>
#import "decode_audio_data.h"
#interface DecoderWrapper : UIViewController {
uint32_t numberOfDecodedData;
uint32_t decodedData[MAX_DECODED_DATA_SIZE];
}
- (void) feedData:(int16_t [])data;
- (uint32_t) numberOfDecodedData;
- (uint32_t *) decodedData;
#end
Now, I'm calling without problem both "feedData" and "numberOfDecodedData" functions, but I'm facing some problems to call "decodedData", that it's supposed to return an array of uint32_t.
How do I NSLog the content of that array? I'm pretty confused because I don't know C and I'm not very confident with pointers....
This is the point where I'm doing the calls:
[decoderWrapped feedData:debug];
if ([decoderWrapped numberOfDecodedData] > 0) {
for (in j=0; j<[decoderWrapped numberOfDecodedData]; j++) {
// how do I print out every position of [decoderWrapped decodedData] ??
}
}
Any help appreciated!
Try
NSLog(#"%u", [decoderWrapped decodedData][j]);
inside of your loop you've got so far.
The short answer is NSLog( #"%d", [[decoderWrapped decodedData][j] ). A uint32_t is really just an unsigned int (related - typedef).
The longer answer is you would want to have a look at the string formatting guide, which is almost identical to C-string formatting, with some additions to handle objects.
uint32_t *decodedData = [decoderWrapped decodedData];
for (int j=0; j<12; j++) {
NSLog(#"%d",decodedData[j]);
}
Related
[programming//in this code i am able only to enter one
value through scan F() FUNCTION although i have used loop up to 5 but when i enter first value program automatically ends whats wrong please answer???][1]
code:
#include<stdio.h>
#include<conio.h>
int main()
{
int arr[5];
int j=0;
if(j<5){
printf("enter\n");
scanf("%d",&arr[j]);
printf("well enter next");
int y;
y=arr[j];
if (y<5)
{ printf("value:%d",arr[j]);
}
j++;
}
return 0;
}
I think you need to figure this out on your own, but let me help you get started.
Let me show you how to store 5 integers taken from the keyboard and you'll have to learn the rest. C is a hard language to start with, so don't be discouraged, I'm still a beginner too.
I will also use some code formatting that I like. There are probably better formats out there but definitely think about how the code looks on the screen.
practice.c
#include<stdio.h>
int main() {
int arr[5];
int j=0;
printf("Enter the first integer:");
while (j<5) {
scanf("%d",&arr[j]);
printf("Next:");
j++;
}
/* I'd then practice printing out the 5 integers.
* Then you can figure out how to stop the loop based on some logical condition.
*/
return 0;
}
Compile with:
gcc -Wall -o practice practice.c
I am starter in os Deving and manage to make a bootloader and then a kernel.I cam successfully jumped to protected mode and transfer the control to kernel.I able to write single characters but printing string is not working.This is my printString() function.
void printString(char * message[]){
int i;
for(i = 0; message[i] != '\0'; i++)
{
print(message[i]);
}
}
And My print Character function is here
void print(char *character){
unsigned char *vidmem = (unsigned char *) VIDEO_ADDRESS;
int offset; //Variable which hold the offset where we want to print our character
offset = GetCursor(); //Setting our offset to current cursor position
vidmem[offset+1] = character;
vidmem[offset+2] = 0x0f;
SetCursor(offset+2);
}
and this is call to function
printString("manoj");
Please help me I am a starter in os deving
I would recommend keeping track of the X and Y coordinates as (static) globals, and using them for offsets into memory. Also, it shouldn't be offset+1 and offset+2, but rather offset and offset+1. This is in addition to what tangrs said in his answer.
A good tutorial for learning how to print to the screen can be found at http://www.jamesmolloy.co.uk/tutorial_html/3.-The%20Screen.html - he goes into great detail about how to print things. It also is a good place to start learning about OSDev, along with the OSDev forums at http://forum.osdev.org/index.php.
There's several things wrong with your functions
Firstly, your print function takes a pointer to a character where it looks like you want the character itself.
Secondly, your printString function is really taking a pointer to pointer to char which isn't what you want if you're calling the printString function like printString("Hello World");.
Your compiler should have warned you about these.
Your code should looks something like this
void printString(char * message){
// ...
}
void print(char character){
// ...
vidmem[offset+1] = character;
// ...
}
When moving file from one place to another, or when replacing file, I always use the methods moveItemAtURL:toURL: or replaceItemAtURL:WithItemAtURL: from NSFileManager.
When calling these methods, I want to determine how much time needed, so that I can use the NSProgressIndicator to tell users how long it's going to take. Just like when you are moving file using OSX, it tells u how much time remaining.
I have looked at the apple doc but couldn't find any information regarding this.
Wondering if this can be implemented, please advise.
You can't know in advance haw long it going to take. What you can do is compute the "percent complete" while you are copying the file. But to do that you need to use lower level APIs. You can use NSFileManagers attributesOfItemAtPath:error to get the file size and NSStreams for doing the copying (there are so many way to do this). Percent complete is bytesWritten / totalBytesInFile.
--- Edit: added sample code as a category on NSURL with a callback block passing the total number of bytes written, percen complete and estimated time left in seconds.
#import <mach/mach_time.h>
#interface NSURL(CopyWithProgress)<NSObject>
- (void) copyFileURLToURL:(NSURL*)destURL withProgressBlock:(void(^)(double, double, double))block;
#end
#implementation NSURL(CopyWithProgress)
- (void) copyFileURLToURL:(NSURL*)destURL
withProgressBlock:(void(^)(double, double, double))block
{
///
// NOTE: error handling has been left out in favor of simplicity
// real production code should obviously handle errors.
NSUInteger fileSize = [[NSFileManager defaultManager] attributesOfItemAtPath:self.path error:nil].fileSize;
NSInputStream *fileInput = [NSInputStream inputStreamWithURL:self];
NSOutputStream *copyOutput = [NSOutputStream outputStreamWithURL:destURL append:NO];
static size_t bufferSize = 4096;
uint8_t *buffer = malloc(bufferSize);
size_t bytesToWrite;
size_t bytesWritten;
size_t copySize = 0;
size_t counter = 0;
[fileInput open];
[copyOutput open];
uint64_t time0 = mach_absolute_time();
while (fileInput.hasBytesAvailable) {
do {
bytesToWrite = [fileInput read:buffer maxLength:bufferSize];
bytesWritten = [copyOutput write:buffer maxLength:bytesToWrite];
bytesToWrite -= bytesWritten;
copySize += bytesWritten;
if (bytesToWrite > 0)
memmove(buffer, buffer + bytesWritten, bytesToWrite);
}
while (bytesToWrite > 0);
if (block != nil && ++counter % 10 == 0) {
double percent = (double)copySize / fileSize;
uint64_t time1 = mach_absolute_time();
double elapsed = (double)(time1 - time0)/NSEC_PER_SEC;
double estTimeLeft = ((1 - percent) / percent) * elapsed;
block(copySize, percent, estTimeLeft);
}
}
if (block != nil)
block(copySize, 1, 0);
}
#end
int main (int argc, const char * argv[])
{
#autoreleasepool {
NSURL *fileURL = [NSURL URLWithString:#"file:///Users/eric/bin/data/english-words.txt"];
NSURL *destURL = [NSURL URLWithString:#"file:///Users/eric/Desktop/english-words.txt"];
[fileURL copyFileURLToURL:destURL withProgressBlock:^(double bytes, double pct, double estSecs) {
NSLog(#"Bytes=%f, Pct=%f, time left:%f s",bytes,pct,estSecs);
}];
}
return 0;
}
Sample Output:
Bytes=40960.000000, Pct=0.183890, time left:0.000753 s
Bytes=81920.000000, Pct=0.367780, time left:0.004336 s
Bytes=122880.000000, Pct=0.551670, time left:0.002672 s
Bytes=163840.000000, Pct=0.735560, time left:0.001396 s
Bytes=204800.000000, Pct=0.919449, time left:0.000391 s
Bytes=222742.000000, Pct=1.000000, time left:0.000000 s
I mostly concur with CRD. I just want to note that under certain common circumstances, both -moveItemAtURL:toURL: and -replaceItemAtURL:WithItemAtURL:... are very fast. When the source and destination are on the same volume, no data has to be copied or moved, only metadata. When the volume is local (as opposed to network-mounted), this typically takes negligible time. That said, it is appropriate to plan for the possibility that they could take significant time.
Also, he mentioned the copyfile() routine for moving files. A copy followed by deleting the original is the necessary approach when moving a file between volumes, but the rename() system call will perform a move within a volume without needing to copy anything. So, a reasonable approach would be to try rename() first and, if it fails with EXDEV, fall back to copyfile().
Finally, the exchangedata() system call can be used as part of a reimplementation of -replaceItemAtURL:WithItemAtURL:....
I don't recommend the approach suggested by aLevelOfIndirection because there are a lot of fiddly details about copying files. It's much better to rely on system libraries than trying to roll your own. His example completely ignores file metadata (file dates, extended attributes, etc.), for example.
The methods moveItemAtURL:toURL: and replaceItemAtURL:WithItemAtURL: are high-level operations. While they provide the semantics you want for the move/replace, as you've found out, they don't provide the kind of feedback you wish during those operations.
Apple is in the process of changing lower-level file handling routines, many are now marked as deprecated in 10.8, so you'll want to pick carefully what you choose to use. However at the lowest levels, system calls (manual section 2) and library functions (manual section 3), there are functions that you can use that are not being deprecated.
One option, there are others, is the function copyfile (manual section 3) which will copy a file or folder hierarchy and provides for a progress callback. That should give you most of the semantics of moveItemAtURL:toURL: along with progress, but you'll need to do more work for replaceItemAtURL:WithItemAtURL: to preserve safety (no data loss in case of error).
If that doesn't meet all your needs you can also look additionally at the low-evel stat and friends to find out file sizes etc.
HTH
I'm just starting out with objective c (coming from java) and I'm working on a calculator program just to practice with the syntax and some basic stuff. The way I'm going about it is having the user input a string and looking through for operators (taking order of operations into account) and then finding the term surrounding that operator, calculating it, replacing the term with the answer, and repeating for all the terms; however, I'm having an issue with the method I'm using to calculate the term. I pass in the index of the operator and have it loop backwards until it hits another operator to find the number immediately before it, and do the same forwards for the number after. My issue is that the loop does not stop when it hits the operators, and instead just continues until the end of the string in both directions. It's probably something really simple that I've overlooked but I've been trying to figure this out for a while and can' seem to get it. I've included an SSCCE of just the first half of the method, with a predetermined string and operator index. (also, a secondary question: is there any better way to post code blocks on this site rather than manually putting in 4 spaces before every line?)
#import <Foundation/Foundation.h>
int firstNumInTerm(int index);
NSString *calculation;
int main(int argc, const char * argv[])
{
#autoreleasepool {
calculation = #"51-43+378*32";
int firstNumber = firstNumInTerm(9);
NSLog(#"The number before the term is: %i", firstNumber);
}
return 0;
}
int firstNumInTerm(int index){
int firstNumIndex = index - 1;
int firstNumLength = 1;
NSRange prevChar = NSMakeRange(firstNumIndex - 1, 1);
while ([calculation substringWithRange:prevChar] != #"*" &&
[calculation substringWithRange:prevChar] != #"/" &&
[calculation substringWithRange:prevChar] != #"+" &&
[calculation substringWithRange:prevChar] != #"-" &&
firstNumIndex > 0) {
NSLog(#"prevChar: %#", [calculation substringWithRange:prevChar]);//TEST
firstNumIndex--; firstNumLength++;
prevChar = NSMakeRange(firstNumIndex - 1, 1);
}
NSRange firstRange = NSMakeRange(firstNumIndex, firstNumLength);
int firstNum = [[calculation substringWithRange:firstRange] intValue];
NSLog(#"firstNum String: %#", [calculation substringWithRange:firstRange]);//TEST
NSLog(#"firstNum int: %i", firstNum);//TEST
return firstNum;
}
The problem with this line:
[calculation substringWithRange:prevChar] != #"*" is that you are comparing the value of two pointers. [calculation substringWithRange:prevChar] returns a pointer to an NSString object, as does the NSString literal statement #"*". The simplest way to compare two strings is by using the isEqualToString: method of NSString. For example:
NSString *myName = #"Stephen";
NSString *yourName = #"Matt";
if([myName isEqualToString:yourName]){
printf("We have the same name!");
}
else{
printf("We do not have the same name");
}
If you are going to be doing a lot of string comparisons, it might be wise to write a macro, such as:
#define STREQ(x,y) [x isEqualToString:y]
Regarding copy/pasting code into StackOverflow:
Since I use XCode 99% of the time, I find it handy to select the text I am going to copy and then hit Cmd-]. This shifts the text to the right one tab-width. I then Cmd-c to copy and then Cmd-[ to undo the right-shift.
You can't do that in Objective-C: [calculation substringWithRange:prevChar] != #"*"
Instead, you need to do :
[[calculation substringWithRange:prevChar] compare:#"*"] != NSOrderedSame
(I know, it's longer, but arithmetic operators aren't overloaded for string like they are in Java).
I see others have answered this to correct the issue with your string comparison operations, but a better way to split this string up would be using NSString's native parsing methods. For example:
NSArray *numbers = [ calculation componentsSeparatedByCharactersInSet:
[ NSCharacterSet characterSetWithCharactersInString: #"*/+-" ] ];
Will give you an array containing each of the numbers (in order) in your string. You could come up with custom parsing routines, but using NSString's is going to likely be more straightforward and a lot less buggy. It will also be easier for someone else to read and understand.
while((![[calculation substringWithRange:prevChar] isEqualToString:#"*"]) && …){
}
or
NSArray *operators = #[#"+", #"-", #"*", #"/"];
while(![operators contains:[calculation substringWithRange:prevChar]])
Is it possible to pass a block of code, for example:
int i = 0;
while (i < [array count]) {
//Code to pass in here
i++;
}
Reason being that i need to perform various actions on every item in an array at different times, it'd be nice to have 1 method and pass it a block of code to run.
Have you considered using blocks. It's just an idea and not working or compilable code
typedef int (^block_t)();
-(void) methodName:(block_t) code_block
{
int i = 0;
while (i < [array count]) {
code_block() //Code to pass in here
i++;
}
block_t youCode = ^{ NSLog("Just an example"); }
[self methodName:youCode];
You can definitely iterate an array and process a block of code on it. This feature has been a standard part of Objective C since 2.0, iOS since 4.0 and in addition was included in Snow Leopard. If you look up the NSArray class reference you will find the following functions:
enumerateObjectsAtIndexes:options:usingBlock:
Executes a given block using the
objects in the array at the specified
indexes.
enumerateObjectsUsingBlock: Executes a
given block using each object in the
array, starting with the first object
and continuing through the array to
the last object.
enumerateObjectsWithOptions:usingBlock:
Executes a given block using each
object in the array.
You can define the code block to be executed globally in your implementation file, or in place where its needed. You can find some good examples on block programming here: http://thirdcog.eu/pwcblocks/.
It sounds like you want "blocks", which are a feature of Objective-C similar to "lambdas", "anonymous functions" and "closures" in other languages.
See Apple's documentation: Blocks Programming Topics
You should put the code into a method and call the method like so:
-(void)foo{
int i = 0;
while (i < [array count]) {
[self myMethod];
i++;
}
}
-(void)myMethod{
//Code to pass in here
}
You could also store the method as a variable allowing you to change which method is called
SEL methodToCall = #selector(myMethod);
-(void)foo{
int i = 0;
while (i < [array count]){
[self performSelector:methodToCall];
i++;
}
}
-(void)myMethod{
//Code to pass in here
}
first of all you could give a more detailed example.
second you could take a look at Action or Func in case you need a return message (well something equivalent for obj-C if exists)
but again, not understanding what you need to do, it is hard to give you an answer
cause from you Q i could understand as #Trevor did that you need to run a method:
int i = 0;
while (i < [array count]) {
if (i % 2)
EvenMethod(array[i])
else
OddMethod(array[i])
i++;
}
If you can live with 4.0+ compatibility, I highly recommend the use of blocks.
- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block
gives you all you need and you can define your block right where you need it. There are some other variants of this, too. Please refer to the 'NSArray' documentation.
Why not just define functions that do what you want, and call them at various times with the items in your array as arguments?
If your concern is that you don't want redundant code with multiple while loops you have here, you could write a function that takes an array and a function as an argument, then applies that function to every element in the array.
Adapted from here:
//------------------------------------------------------------------------------------
// 2.6 How to Pass a Function Pointer
// <pt2Func> is a pointer to a function which returns void and takes an NSObject*
void DoForAllItems( NSArray* array, void (*pt2Func)(NSObject*) )
{
int i = 0;
while (i < [array count]) {
(*pt2Func)([array objectAtIndex:i]);
i++;
}
}
// 'DoIt' takes an NSObject*
void DoIt (NSObject* object){ NSLog(#"DoIt"); }
// execute example code
void Pass_A_Function_Pointer()
{
NSArray* array= [NSArray arrayWithObjects:#"1", #"2", nil];
DoForAllItems(array, &DoIt);
}
http://thirdcog.eu/pwcblocks/#objcblocks
Blocks were added recently to Objective-C I hope they have found their way to the Iphone also.
and it was anwered here also before:
Using Objective-C Blocks
Regards
If you are using Objective C++, I would strongly recommend function objects (even over blocks). They have a nice syntax, are easy to use, and are supported everywhere on modern C++ compilers (MSVC++11, GNUC++11, and LLVMC++11):
void go( function<void (int arg)> func )
{
int i = 0;
while (i < [array count]) {
//Code to pass in here
func( i ) ; // runs func on i
i++;
}
}
calling it:
go( []( int arg ){ // the square brackets are the "capture"
printf( "arg was %d\n", arg ) ; // arg takes on whatever value was passed to it,
// just like a normal C function
} ) ;