Thread: Input multiple floats directly to array

  1. #1
    Registered User
    Join Date
    Nov 2019
    Posts
    135

    Input multiple floats directly to array

    Hey, so this term I'm taking C/C++ course, and I'm tasked with some exercises in C programming.

    Here is one:

    Write a program that reads in two vectors and calculates the inner product between them, as follows:
    1. Read in the length of the vectors (an integer followed by a newline).
    2. Read in the two vectors (floats separated by spaces, newline separating the vectors).
    3. The inner (scaler) product is the sum of the multiplication of each two elements:
      • If the vectors are [1, 0.5, 0] and [0.2, 1, 0.3] the inner product is: 1 * 0.2 + 0.5 * 1 + 0 * 0.3 = 0.7.

    4. Print the result up to 2 digits after the decimal point (hint: "%.2f").

    You may assume the input is valid, but you may not assume a maximum length.

    For example:
    Input Result
    3
    1 0.5 0
    0.2 1 0.3
    0.70
    0 0.00


    I thought first to input the lengths of both the vectors and then define the vectors in the suitable lengths (by pointers).

    But my problem is with the input of the coordinates - as it's in one row, so I don't know how I can insert efficiently and elegantly floats directly to the arrays.

    Does someone have an idea how can I input the coordinates correctly?
    Thank in advance!
    Last edited by HelpMeC; 11-30-2019 at 11:50 AM.

  2. #2
    Registered User
    Join Date
    Aug 2019
    Location
    Inside a Singularity
    Posts
    229
    This should work, you needn't worry about the spaces and newlines when using cin. As soon as a space or newline is encountered, it automatically determines that you wanna fill in the next variable.

    Code:
    int main (void)
    {
        int SizeOfVector; std::cin >> SizeOfVector;
    
        float* Vec1 = new float [SizeOfVector];
        float* Vec2 = new float [SizeOfVector];
    
        int i;
    
        for (i = 0; i < SizeOfVector; i++)
            std::cin >> Vec1[i];
    
        for (i = 0; i < SizeOfVector; i++)
            std::cin >> Vec2[i];
    
        float Result = 0.0f;
    
        for (i = 0; i < SizeOfVector; i++)
            Result += (Vec1[i] * Vec2[i]);
    
        std::cout << Result;
    
        delete [] Vec2;
        delete [] Vec1;
    
        return 0;
    }
    [EDIT]
    Crap, just realised that this was posted in the C Programming section. You do make a mention of C/C++ though. You can change the cin to:

    Code:
    scanf ("%[^\n]f" , &SizeOfVector); // for input of Vector Size. It can also probably be just scanf ("%f" , &SizeOfVector) but I'm not sure as I don't know much of C
    
    for (int i = 0; i < SizeOfVector; i++)
           scanf ("%f" , &VecX[i]); // Again, not exactly sure what it's supposed to be. You will be able to figure it out...
    and cout to printf.

    You can replace malloc and free for new and delete. Also, you can make use of the fact that scanf can input until it encounters whitespace, newline or eof.
    [/EDIT]
    Last edited by Zeus_; 11-30-2019 at 01:08 PM.

  3. #3
    Registered User
    Join Date
    Nov 2019
    Posts
    135
    Quote Originally Posted by Zeus_ View Post
    This should work, you needn't worry about the spaces and newlines when using cin. As soon as a space or newline is encountered, it automatically determines that you wanna fill in the next variable.

    Code:
    int main (void)
    {
        int SizeOfVector; std::cin >> SizeOfVector;
    
        float* Vec1 = new float [SizeOfVector];
        float* Vec2 = new float [SizeOfVector];
    
        int i;
    
        for (i = 0; i < SizeOfVector; i++)
            std::cin >> Vec1[i];
    
        for (i = 0; i < SizeOfVector; i++)
            std::cin >> Vec2[i];
    
        float Result = 0.0f;
    
        for (i = 0; i < SizeOfVector; i++)
            Result += (Vec1[i] * Vec2[i]);
    
        std::cout << Result;
    
        delete [] Vec2;
        delete [] Vec1;
    
        return 0;
    }
    [EDIT]
    Crap, just realised that this was posted in the C Programming section. You do make a mention of C/C++ though. You can change the cin to:

    Code:
    scanf ("%[^\n]f" , &SizeOfVector); // for input of Vector Size. It can also probably be just scanf ("%f" , &SizeOfVector) but I'm not sure as I don't know much of C
    
    for (int i = 0; i < SizeOfVector; i++)
           scanf ("%f" , &VecX[i]); // Again, not exactly sure what it's supposed to be. You will be able to figure it out...
    and cout to printf.

    You can replace malloc and free for new and delete. Also, you can make use of the fact that scanf can input until it encounters whitespace, newline or eof.
    [/EDIT]
    I have adapted your solution and it's excellent.
    Thank you!

    Code:
    int main (void)
    {
        size_t sizeOfVector;
        scanf("%zu", &sizeOfVector);
        
        float* vec1 = (float*)malloc(sizeof(float) * sizeOfVector);
        float* vec2 = (float*)malloc(sizeof(float) * sizeOfVector);
     
        size_t i;
     
        for (i = 0; i < sizeOfVector; i++) {
            scanf("%f" , &(vec1[i]));
        }
    
    
        for (i = 0; i < sizeOfVector; i++) {
            scanf("%f" , &(vec2[i]));
        }
     
        float result = 0.0f;
     
        for (i = 0; i < sizeOfVector; i++) {
            result += (vec1[i] * vec2[i]);
        }
     
        printf("%f\n", result);
        
        free(vec1);    free(vec2);
    
    
    
        return 0;
    }
    Last edited by HelpMeC; 11-30-2019 at 02:59 PM.

  4. #4
    Registered User
    Join Date
    Aug 2019
    Location
    Inside a Singularity
    Posts
    229
    Cheers, and thanks to you too! I get to learn C without even having to refer to guides by just looking at code others post. Googling things I don't understand helps me catch up.

  5. #5
    Registered User
    Join Date
    Nov 2019
    Posts
    135
    Quote Originally Posted by Zeus_ View Post
    Cheers, and thanks to you too! I get to learn C without even having to refer to guides by just looking at code others post. Googling things I don't understand helps me catch up.

  6. #6
    Registered User
    Join Date
    Nov 2019
    Posts
    135
    Quote Originally Posted by HelpMeC View Post
    I have adapted your solution and it's excellent.
    Thank you!

    Code:
    int main (void)
    {
        size_t sizeOfVector;
        scanf("%zu", &sizeOfVector);
        
        float* vec1 = (float*)malloc(sizeof(float) * sizeOfVector);
        float* vec2 = (float*)malloc(sizeof(float) * sizeOfVector);
     
        size_t i;
     
        for (i = 0; i < sizeOfVector; i++) {
            scanf("%f" , &(vec1[i]));
        }
    
    
        for (i = 0; i < sizeOfVector; i++) {
            scanf("%f" , &(vec2[i]));
        }
     
        float result = 0.0f;
     
        for (i = 0; i < sizeOfVector; i++) {
            result += (vec1[i] * vec2[i]);
        }
     
        printf("%f\n", result);
        
        free(vec1);    free(vec2);
    
    
    
        return 0;
    }
    About that solution in C -

    I notice now that the loops iterate over the scanf in some manner I wouldn't expect.
    But it works - how is it?

    First, the user sends the sizeOfVector number - and press newline - we have got the size.

    But the next step is: the user fills a line: <float number>\whitespace<float number>\whitespace<float number>\newline
    For example:
    1 0.55 2.1

    In some way, this scanf actually inputs only one float per iteration, but how does it "know" to split the line into three sections of floats respectively?

    Thank you.

  7. #7
    Registered User
    Join Date
    Aug 2019
    Location
    Inside a Singularity
    Posts
    229
    scanf reads until it encounters a whitespace, a newline or an eof character. So, when you type in that space b/w 1 and 0.55, scanf stops taking in input for the first float (which is 1 and also your first iteration) and starts taking in input for the second float (i.e. 0.55, in your second iteration). It doesn't "know" to split the line into three sections of float or as a matter of fact, SizeOfVector sections of floats. It simply reads until it encounter one of the above mentioned characters and stops reading. Then that loop iteration gets over. And then you start another loop iteration and this keeps of happening again and again until the test condition is violated.
    "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook, The Wizardry Compiled

  8. #8
    Registered User
    Join Date
    Dec 2017
    Posts
    778
    Quote Originally Posted by Zeus_ View Post
    scanf reads until it encounters a whitespace, a newline or an eof character.
    Not necessarily. It depends on the format spec. %d simply stops when it encounters a non-digit (which may or may not be a space).
    %s reads only up to the first whitespace, but %[^\n], for example, stops when it encounters a newline (but not other whitespace).
    The world hangs on a thin thread, and that is the psyche of man. - Carl Jung

  9. #9
    Registered User
    Join Date
    Nov 2019
    Posts
    135
    Quote Originally Posted by john.c View Post
    Not necessarily. It depends on the format spec. %d simply stops when it encounters a non-digit (which may or may not be a space).
    %s reads only up to the first whitespace, but %[^\n], for example, stops when it encounters a newline (but not other whitespace).
    Yes, this point was the next I wanted to ask Zeus about.
    BTW, %s doesn't get whitespaces? I didn't use the %[^\n] specifier much.

  10. #10
    Registered User
    Join Date
    Aug 2019
    Location
    Inside a Singularity
    Posts
    229
    > BTW, %s doesn't get whitespaces?

    Nope, you'd probably have to do something like scanf ("%[^\n]s", string) to input a string with spaces until the user hits enter

    >
    I didn't use the %[^\n] specifier much.

    You don't need to wrt this problem. For %f here, as soon as you encounter a space or newline char, scanf stops taking the input and you continue on with your iterations.

    Not necessarily. It depends on the format spec. %d simply stops when it encounters a non-digit (which may or may not be a space).
    %s reads only up to the first whitespace, but %[^\n], for example, stops when it encounters a newline (but not other whitespace).




    Yea, that's there. I was speaking in general terms meaning that these are the minimum conditions for scanf to stop taking input unless you specify differently.
    "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook, The Wizardry Compiled

  11. #11
    Registered User
    Join Date
    Nov 2019
    Posts
    135
    Thank you guys.

  12. #12
    Registered User
    Join Date
    Nov 2019
    Posts
    135
    Deleted.
    Last edited by HelpMeC; 12-04-2019 at 02:11 PM.

  13. #13
    Registered User
    Join Date
    Aug 2019
    Location
    Inside a Singularity
    Posts
    229
    The format specifier for int is %d.

    Format Specifiers in C

    EDIT: Lol, why the delete ;). There's nothing to be worried. No one will judge you and even if they do, it doesn't matter. We're all learning things and it's easy to get confused and do simple, sometimes stupid, mistakes but that's okay :)
    Last edited by Zeus_; 12-04-2019 at 02:19 PM.
    "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook, The Wizardry Compiled

  14. #14
    Registered User
    Join Date
    Nov 2019
    Posts
    135
    @Zeus_
    No, it's all right, I wasn't embarrassed, on the contrary I have opened a topic about that.
    And thank you for the encouragement dude!

    Yea, I know this is also a format of integer but something weird is happening with the university's tests when I use only the specifier without nothing else:

    Code:
    int main(){
        // The string
        int len = 0;
        scanf("%i\n", &len);
        if (len == 0) {
            return 0;
        }
        
        char* str = (char*)malloc(sizeof(char) * len + 1); // Plus 1 for null-terminator
        scanf("%[^\n]s", str);
    
    
        // The n that will sum the result
        int n = 0;
    
    
        for (int i = 0; i < len - 1 && str[i] != '\0'; i++){
            if (str[i] == str[i+1]) {
                n++;
            }
        }
        if (n == 0) {
            free(str);
            return 0;
        }
        //Print from n to 2n
        for (int i = n; i <= 2*n; i++){
            printf("%c", str[i]);
        }
    
    
        free(str);
        
        return 0;
    }
    Look at the first scanf - if I change it to be:

    Code:
        scanf("%i\n", &len);
    Then some tests are failed like the following one...

  15. #15
    Registered User
    Join Date
    Aug 2019
    Location
    Inside a Singularity
    Posts
    229
    Difference between %d and %i format specifier in C language - GeeksforGeeks

    Maybe this will help.
    I don't see a lot of people using %i...

    Also, why is it this?
    Code:
    for (int i = 0; i < len - 1 && str[i] != '\0'; i++)
    
    // len + 1 (for '\0') is the length of your string. So, you should do just this:
    
    for (int i = 0; i < len - 1; i++)
    
    // or
    
    for (int i = 0; str[i + 1] != '\0'
    
    // I can't understand why you'd put those two conditions in there
    "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook, The Wizardry Compiled

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. pass array directly to new object
    By a.mlw.walker in forum C++ Programming
    Replies: 3
    Last Post: 06-14-2013, 03:03 PM
  2. Replies: 3
    Last Post: 04-09-2010, 05:07 AM
  3. how to fill multiple array locations with one input
    By kryonik in forum C++ Programming
    Replies: 5
    Last Post: 06-08-2006, 10:12 PM
  4. Replies: 3
    Last Post: 04-30-2006, 06:01 AM
  5. Input stream directly to structure elements?
    By thenrkst in forum C++ Programming
    Replies: 1
    Last Post: 04-24-2003, 11:43 AM

Tags for this Thread