2nd Edition challenge: User Input

Hi,

this is my first post to the forum, I just started work on the book this weekend. The below seems to be a succesful answer to the challenge but I suspect is not as elegant as it could be. I was hoping to get some constructive criticism on how I could improve it.

[code]#include <stdio.h>
#include <readline/readline.h>
#include <stdlib.h>

//get user input and pass back int value

char getUserInput(char *userResponse){

    const char *userString = readline(NULL);

    int userInt = atoi(userString);

// printf("%d \n", userInt);

return userInt;

}

int main(int argc, const char * argv[])
{

printf("Where should I start counting? \n");

        for (int i = getUserInput(NULL); i >= 0; --i) {
            
            if (i % 3 == 0){
            
                printf("%d \n", i);
                
                if (i % 5 == 0){
                    
                    printf("Found one!\n");
                    continue;
                }
                
            }
        
        }
            
return 0;

}
[/code]

Change:

//get user input and pass back int value

char getUserInput(char *userResponse){
   const char *userString = readline(NULL);
    
   int userInt = atoi(userString);
    
   // printf("%d \n", userInt);
    
   return userInt;
}

To:

//get user input and pass back int value

int getUserInput ()
{
    const char *inputString = readline (NULL);
    int userInt = atoi (inputString);    
    return userInt;
}

To delete the unused parameter, and to return an int not a char.

You could also add some code to warn the user if the input string is not an integer.

Thanks, much appreciated, I will have have a play with that.

Hello,

I wrote one like this, it reads fine my input and logs fine, but

  • import? include? I’m not sure which word should I use, so far I read until Chapter8.
  • my code works good without a line of “#include <stdlib.h>”, but Xcode warns me “implicit declaration of function ‘atoi’ is invalid in c99”.
    -> I think that no warnings is best so I just include stdlib.h to avoid any troubles?

[code]#import <readline/readline.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, const char * argv[])
{
printf(“Where should I start counting? “);
int number = atoi(readline(NULL));
for (int i = number; i > -1; i -= 3) {
printf(”%d\n”, i);
if (i % 5 == 0) {
printf(“found one!\n”);
}
}
return 0;
}[/code]

This is my attempt. Seems to work but is there a simpler way?

#include <stdio.h>
#include <readline/readline.h>
#include <stdlib.h>
int i;

int userInput() {
const char *inputString = readline((NULL));
//convert user input from string to integer;
int userInt = atoi(inputString);
//return the user input as the value for inputString;
return userInt;
}
int main(int argc, const char * argv[])
{
//asks user for input;
printf(“Where shall I start counting from? \n”);
//call userInput function;
const char *userInput = readline(NULL);
//run for statement checking input is equal to or above 0 and then removing 3 from input;
for (i = atoi(userInput); i >= 0; i = i - 3) {
printf("%d\n", i);
//checks for multiples of 5 in input and prints “found one” if it is;
if (i % 5 == 0) {
printf(“Found one.\n”);
continue;
}
}
return 0;
}

How come you are not calling the userInput () function which you have defined?

I’ve done it with a while loop :slight_smile:

#include <stdio.h>
#include <readline/readline.h>
#include <stdlib.h>

int main(int argc, const char * argv[])
{
    printf("Where should I begin counting? ");
    const char *num = readline(NULL);
    
    int i = atoi(num);
    
    while (i > 0) {
        printf(" %d \n", i);
        i-=3;
        if (i % 5 == 0 ) {
        printf("Found one:%d\n", i);
            
    }
    }
    
    return 0;
}

The output is ok

This is the solution I came up with. I had to search here to add line 3 as well.

[code]#import <readline/readline.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, const char * argv[])
{
// Prompt user for starting point
printf(“Where should I start counting? \n”);
const char *startingPointInput = readline(NULL);

// Initialize loop to count down from 99 to 0
for (int i = atoi(startingPointInput); i > -1; i--) {
    
    // Set condition to only regard numbers divisible by 3
    if (i % 3 == 0) {
        printf("%i\n", i);
        
        // Search for numbers also divisible by 5
        if (i % 5 == 0) {
            printf("Found one!\n");
            
        } // End search for numbers divisible by 5
        
    } // End count down from 99 to 0
    
} // End discrimiinator for numbers divisible by 3
return 0;

} // Terminate main[/code]

My solution is not the fastest but helps me follow the logic even on my worst day :slight_smile:

#import <readline/readline.h>
#include <stdio.h>

int main(int argc, const char * argv[])
{

printf("Enter the starting countdown number: ");

//readline(null) returns a user’s entered string so we can’t assign it to an int type. We first have to assign it to a char type. Then convert it to a string.
const char *number = readline(NULL);

//1st crucial step: let’s convert user input to an int type
int userInput = atoi(number);

//2nd crucial step: make sure to assign the user input as the value to be used in our for loop.
for (int i = userInput; i >= 0; i–) {
if (i % 3 == 0) {
printf("%d\n",i);

        if (i % 5 == 0) {
            printf("Found one!\n");
        }
    }
}

return 0;

}

I came up with the following, but I can’t get it to work:

[code]#include <stdio.h>
#include <stdlib.h>
#include <readline/readline.h>

int main(int argc, const char * argv[])
{
printf(“Where should we begin?\n”);
const char *start = readline(NULL);

for (int i = atoi(start); i >= 0; i -= 3) {
    printf("%d\n", i);
    if (i % 5 == 0) {
        printf("Found One!\n");
    }
}
return 0;

}[/code]

I keep getting two Apple Mach-O Linker Errors. I’m brand new to this, and appreciate any help!

File: main.c
Adding library to countdown project> Build Phases> Link Binary With Libraries: libreadline.dylib

[code]#include <stdio.h>
#include <stdlib.h>
#include <readline/readline.h>

int main(int argc, const char * argv[])
{

// Challenge: Counting down (Chapter 8 Loops)
// Program that counts backward from 99 through 0 by 3, printing each number
// If the number is divisible by 5, it should also print the words "Found one!".
// Prompt the user for input and then kick off the countdown from the desired spot.
// using readline and atoi functions

printf("Countdown begin from? ");
const char *start = readline(NULL);

for (int i = atoi(start); i >= 0; i-=3) { // i-=3 shorthand of i = i + 3
    printf("%d\n", i);
    if (i % 5 == 0) { // divisible by 5
        printf("Found one!\n");
    }
}

return 0;

}
[/code]
Output:
42
39
36
33
30
Found one!
27
24
21
18
15
Found one!
12
9
6
3
0
Found one!
Program ended with exit code: 0

Perfect, thanks!

Greetings everyone.

I am new here and I’m really jazzed about this book & this forum!

… and HERE IT IS!!

[code]#include <stdio.h>
#include <readline/readline.h> // this file declares the readline function

int main(int argc, const char * argv[])
{
printf(“Where should the count begin?”);
const char *number = readline(NULL); // here user inputs the number & stores it in the string ‘number’

int num = atoi(number); // the 'number' string is converted into an integer through the 'atoi' function

for (int i = num; i >= 0; i -= 3) // the integer num is embedded into the for loop
  {
     printf("%d \n", i);

     if (i % 5 == 0) // check if i is divisible by 5 by using the modulus operator
        {
           printf("FOUND ONE!! \n");
        }
  }
  printf("%d\n",0); // 0 is printed at the end so the program lives up to the conditons of the challenge
  printf("I DID IT!!\n");  // this is printed to express my joy of getting this challenge first try
  return 0;

}[/code]

What do you think?

[color=#004080]JR[/color]

I am having a very difficult time trying to get this to work.
The code looks fine, but when I input something, the readline function ignores it.
-note: readline worked in the coolness exercise, but only for letters. I tried inputing numbers in the coolness exercise and the readline function ignored that. I would assume that if I input the number 25 to the readline function, it would come back as a string such as “25”.

I’ve tried switching import/include, still no luck.
Also, I did include the link to libreadline.dylib

I am using Xcode6.

Please help.
Thanks!

#include <stdio.h>
#include <readline/readline.h>
#include <stdlib.h>

int main(int argc, const char * argv[])
{
    printf("Where shall we begin?\n");
    //take user input
    const char *startHere = readline(NULL);
    //confirm user input
    printf("Start counting at %s!\n\n", startHere);
    //convert user input
    int i = atoi(startHere);
    while (i >=0) {
        printf("%d\n", i);
        if (i % 5 == 0) {
            printf("Found one!\n");
        }
        i -= 3;
    }
    return 0;
}

Hey guys,

Super new to this whole thing and only been working on it for about a day, but I only saw 1 other post that included the readline in the atoi function. It runs smoothly and doesn’t require the extra lines that I see in most of the posts here, but I’m not sure if this is something I can get away with all the time or just a lucky coincidence. Any thoughts?

[code]#import <readline/readline.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, const char * argv[]) {
//Write a program that counts backward from 99 through 0 by 3, printing each number
//Have every number countdown 0 through 99, but need to count by 3s
//Prompt user to input starting number using readline() and atoi()
printf(“Where should I start couting? “);
for (int i = atoi(readline(NULL)); i >= 0; i-=3) { //Line will not loop, not executing increment
printf(”%d.\n”, i);

    if (i % 5 == 0) {
    printf("Found One!\n");
        continue;
    }
} //Correct bracket placement fixed increment issue
         return 0;
}[/code]

[quote][code]

for (int i = atoi (readline (NULL)); i >= 0; i-=3) { //Line will not loop, not executing increment
printf("%d.\n", i);

    if (i % 5 == 0) {
         printf("Found One!\n");
         continue;
    }
} 

[/code][/quote]
There is nothing wrong with that; it is quite compact.

However, it is not considered good practice to write code like that, attempting to minimise the number of lines of code. For example, one reason is that it simply makes debugging the code harder by using a debugger.

The following code is better:

...
const int start = atoi (readline (NULL));
for (int i = start; i >= 0; i-=3) {
        printf ("%d.\n", i);
        
        if (i % 5 == 0) {
            printf ("Found One!\n");
        }
}

The following code is even much better:

...
const char * input = readline (NULL);
const int start = atoi (input);
for (int i = start; i >= 0; i-=3) {
        printf ("%d.\n", i);
        
        if (i % 5 == 0) {
             printf ("Found One!\n");
        }
}

I came up with the following for the challenge. One thing I noticed, entering in the number using the numeric keypad errors. Using numbers from keyboard works fine.

[code]#include <stdio.h>
#include <stdlib.h>
#include <readline/readline.h>

int main(int argc, const char * argv[])
{
printf("Where should I start counting? ");
const char *num = readline(NULL);

int numInt = atoi(num);

for (int i = numInt; i >= 0; i-=3) {
    printf("%d\n", i);
    if (i % 5 == 0) {
            printf("Found one!\n");
        }

    }

return 0;

}[/code]

I struggled with this one for a while, having the same issues as most people here. It turned out I had forgotten to add libreadline.dylib under ‘Link Binary With Libraries’ in ‘Build Phases’. The book walks you through this stage but I did it on the ‘Coolness’ task and then neglected to do it on ‘CountDown’. Perhaps I am the only one to make this mistake but I still think it is worth mentioning in case I am not alone here.

For the record, here is my code:


#import <readline/readline.h>
#include <stdio.h>
#include <stdlib.h>


int main(int argc, const char * argv[])
{
    //ask the user which number to use
    printf("Where should I start counting?");
    
    //read the number that the user enters
    const char *num = readline(NULL);
    
    //convert the string to integer and call it userValue
    int userValue = atoi(num);
    
    for (int i = userValue; i >= 0; i -= 3) {  // This line describes the situation to check for
        if (i % 5 == 0) {
            printf("%d\n", i);
            printf("Found one!\n");  // These 3 lines say if i is divisable by 5, say "I found one"
            continue;
        }
        printf("%d\n", i); // Print the number that i equates to
    }
    return 0;
}

Please provide feedback if you think this can be done better.

ibex10, once I included readline and the stdlib and stdio headers, I was able to program this simple example. My solution is viewable in another tread. My question is: when did the language change to require these includes? This is the first time that the examples in the book (Objective C v2) required additional resources other than what was printed to get working.

And had another user not printed the #include <readline/readline.h> solution, I would have been at a standstill.

I’ve tried doing a finder-level search for readline, to see if I could have found it that way, but it doesn’t show up.

I guess what I’m asking is: how could I have found that on my own, without somebody else just telling me?

Thanks in advance.

Chris Conlee

PS: I’m still interested in hiring you to teach me some stuff, but I want to get thru the book. Life kind of got in the way the past 6 months. I will still be doing your programming exercise that you sent me, too. Soon. :slight_smile:

You have to first learn how to write code without Xcode :slight_smile: Once you have done that, you are ready to use Xcode, which provides a thick layer of magic between the programmer and the machine.