How to use scanf in a Swift environment - oop

I am practicing Objective C to get a better understanding of C and was using the newest Xcode, but using the terminal to write simple programs. In the the program below is can't seem to get the scanf function to work. Is there a different function that I can use to input data into the terminal to check the rest of syntax and coding?
#import <Foundation/Foundation.h>
int main (int argc, char *argv[])
{
int n, number, triangularNumber;
NSLog (#"What triangular number do you want?");
scanf ("%i", &number);
triangularNumber = 0;
for ( n = 1; n <= number; ++n )
triangularNumber += n;
NSLog (#"Triangular number %i is %i\n", number, triangularNumber);
return 0;
}

You can't have a space in between the scanf and (). The scanf function should turn purple when done correctly. Just take out the space and you should be fine.

You can try this (this is Swift, Objective C is the same):
let handle = NSFileHandle.fileHandleWithStandardInput()
let input = NSString(data: handle.availableData, encoding: NSUTF8StringEncoding)

Related

Using arg[v] as int? - Objective C

I'm trying to pass arguments into and integer variable at the start of my program in xcode using Objective C. So far most methods I've found have just given me a variety of error messages or crashed my VM.
int numcols, numrows;
int main(int argc, const char * argv[]) {
#autoreleasepool {
if (argc != 3){
NSLog(#"%2s", "Wrong number of arguments");
exit(1);
}
//numrows = (int)(argv[1] - '0');
//numcols = (int)(argv[2] - '0'); These lines cause a crash
numrows = 3;
numcols = 4;
I want numrows to take the first argument and numcols to take the second. I went into the settings in xcode to change the starting arguments to 3 and 4, but if I check them or print them they come out as random numbers.
argv is an array of C strings. You cannot just cast a string to an integer, you need to parse the string to produce the integer value it represents.
You could write code to do this yourself, but fortunately there are library functions which handle this, for example see strtol which will parse a string and produce a long.
HTH
First of all your question is not clear, how much i understand i can say. As argc means argument count and argv means argument value. If you want to cast char to int. try this
[[NSString stringWithFormat:#"%s", argv[2]] intValue];

scanf function in objective-c, float and double

I just a beginner in objective-C.
Below is a calculator of temperature.
I find a solution on the internet. The problem is the scanf.
At first, I set the f as a double, but program has problem.
So I change it to float.
May I ask what's going on on scanf function in objective-c?
Only can set character, int and float?
Another question is, what if I want to set a double, to use in another function which only accept double variable?
Thanks
import
int main(int argc, const char * argv[])
{
#autoreleasepool {
double c;
float f;
NSLog(#"Please enter F temp");
scanf("%f", &f);
c = (f-32) / 1.8;
//c = 1.3E-3;
// insert code here...
NSLog(#"The C temp is %.3f", c);
}
return 0;
}
Use %f for float and %lf for double. However be sure to check the return value from scanf() (or sscanf()) to ensure it parsed the correct number of values:
double d;
printf("Entry thy number mortal: ");
if (scanf("%lf", &d)) == 1) {
printf("Oh that's nice, you entered %f\n", d);
}

Scanf countdown

I am making a scanf countdown via objective-C, so the program will count down from what ever number you input. However, there's an annoying semantic error in the code saying:Data argument not used by format string. Also the program doesn't countdown, it just displays the output as zero once I input a number.
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
#autoreleasepool {
int x,number;
NSLog(#"please enter a number:");
scanf("i", &number);
for (x = number; x>=0; x--)
NSLog(#"%i",x);
}
return 0;
}
You need to pass %i, not i in the format string of scanf.
When you pass i, the format string has zero format specifiers, leading to the semantic analyzer to produce a warning. That's also the reason why nothing gets entered into your number variable, so the countdown does not happen either.

Convert really large decimal string to hex?

I've got a really large decimal number in an NSString, which is too large to fit into any variable including NSDecimal. I was doing the math manually, but if I can't fit the number into a variable then I can't be dividing it. So what would be a good way to convert the string?
Example Input: 423723487924398723478243789243879243978234
Output: 4DD361F5A772159224CE9EB0C215D2915FA
I was looking at the first answer here, but it's in C# and I don't know it's objective C equivalent.
Does anyone have any ideas that don't involve using an external library?
If this is all you need, it's not too hard to implement, especially if you're willing to use Objective-C++. By using Objective-C++, you can use a vector to manage memory, which simplifies the code.
Here's the interface we'll implement:
// NSString+BigDecimalToHex.h
#interface NSString (BigDecimalToHex)
- (NSString *)hexStringFromDecimalString;
#end
To implement it, we'll represent an arbitrary-precision non-negative integer as a vector of base-65536 digits:
// NSString+BigDecimalToHex.mm
#import "NSString+BigDecimalToHex.h"
#import <vector>
// index 0 is the least significant digit
typedef std::vector<uint16_t> BigInt;
The "hard" part is to multiply a BigInt by 10 and add a single decimal digit to it. We can very easily implement this as long multiplication with a preloaded carry:
static void insertDecimalDigit(BigInt &b, uint16_t decimalDigit) {
uint32_t carry = decimalDigit;
for (size_t i = 0; i < b.size(); ++i) {
uint32_t product = b[i] * (uint32_t)10 + carry;
b[i] = (uint16_t)product;
carry = product >> 16;
}
if (carry > 0) {
b.push_back(carry);
}
}
With that helper method, we're ready to implement the interface. First, we need to convert the decimal digit string to a BigInt by calling the helper method once for each decimal digit:
- (NSString *)hexStringFromDecimalString {
NSUInteger length = self.length;
unichar decimalCharacters[length];
[self getCharacters:decimalCharacters range:NSMakeRange(0, length)];
BigInt b;
for (NSUInteger i = 0; i < length; ++i) {
insertDecimalDigit(b, decimalCharacters[i] - '0');
}
If the input string is empty, or all zeros, then b is empty. We need to check for that:
if (b.size() == 0) {
return #"0";
}
Now we need to convert b to a hex digit string. The most significant digit of b is at the highest index. To avoid leading zeros, we'll handle that digit specially:
NSMutableString *hexString = [NSMutableString stringWithFormat:#"%X", b.back()];
Then we convert each remaining base-65536 digit to four hex digits, in order from most significant to least significant:
for (ssize_t i = b.size() - 2; i >= 0; --i) {
[hexString appendFormat:#"%04X", b[i]];
}
And then we're done:
return hexString;
}
You can find my full test program (to run as a Mac command-line program) in this gist.

using if statements with a string of letters and user input

Helllo I am still new to programing and had a question about using if statements while using user input with the research I have conducted i can't seem to find what I am doing wrong?
Below is my posted simple multiplication calculator.
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) {
int a ;
int b ;
int c ;
printf("\n");
printf("\n");
printf("Welcome to calculator");
printf("\n");
printf("\n");
printf("what would you like to choose for first value?");
scanf("%d", &a);
printf("\n");
printf("What would you like to input for the second value?");
scanf("%d", &b);
c = a * b;
printf("\n");
printf("\n");
printf(" Here is your product");
printf("\n");
NSLog(#"a * b =%i", c);
char userinput ;
char yesvari = "yes" ;
char novari = "no";
printf("\n");
printf("\n");
printf("Would you like to do another calculation?");
scanf("%i", &userinput);
if (userinput == yesvari) {
NSLog(#" okay cool");
}
if (userinput == novari) {
NSLog(#"okay bye");
}
return 0;
}
You are scanning the character incorrectly with %i and you need to compare them using strcmp. If you are looking for a string from the user you need to use %s and you need a character buffer large enough to hold the input.
Try this
//Make sure userinput is large enough for 3 characters and null terminator
char userinput[4];
//%3s limits the string to 3 characters
scanf("%3s", userinput);
//Lower case the characteres
for(int i = 0; i < 3; i++)
userinput[i] = tolower(userinput[i]);
//compare against a lower case constant yes
if(strcmp("yes", userinput) == 0)
{
//Logic to repeat
printf("yes!\n");
}
else
{
//Lets just assume they meant no
printf("bye!\n");
}
I think you are reading a char using the wrong format %i: scanf("%i", &userinput);
And I think it is a better to use #NSString instead of simple char (I am not even sure what will happen in ObjC if you write char a = "asd", since you are giving a char a char[] value) . In that case, since strings are pointers, you cannot use == to compare them. You could use isEqualToString or isEqualTo instead. If you are interested in the difference between the two, look at this post would help.
In C, you can't compare strings using ==, so you would have to use a function like strcmp(), like this:
if ( !strcmp(userinput, yesvari) ) {
//etc.
}
The bang (!) is used because strcmp() actually returns 0 when the two strings match. Welcome to the wonderful world of C!