0

A function containing the function of a vector is included in a class called Vector. I will determine which function to use in the main function by the string entered in the txt file.

class Vector
{
public: // private?
    double x, y, z;

public:
    Vector() {
        x = 0;
        y = 0;
        z = 0;
    }
    Vector(int _x, int _y, int _z) {
        x = _x;
        y = _y;
        z = _z;
    }
    Vector Add(Vector v) {
        Vector output;
        output.x = x + v.x;
        output.y = y + v.y;
        output.z = z + v.z;
        return output;
    }
    double Dot(Vector v) {
        double output;
        output = (x * v.x) + (y * v.y) + (x * v.y);
        return output;
    }
};

This is the main function. I want to use the string that I want to receive in the txt file, but it doesn't work well. A detailed example is below this code.

int main()
{
    FILE* fpInput;
    FILE* fpOutput;
    int vectorAx, vectorAy, vectorAz, vectorAdim;
    int vectorBx, vectorBy, vectorBz, vectorBdim;
    char VecFun[10];

    fpInput = fopen("input.txt", "r");

    fscanf(fpInput, "%d %d %d", &vectorAx, &vectorAy, &vectorAz);
    fscanf(fpInput, "%d %d %d", &vectorBx, &vectorBy, &vectorBz);

    fclose(fpInput);

    fpInput = fopen("input.txt", "r");
    fgets(VecFun, sizeof(VecFun), fpInput);
    fclose(fpInput);

    Vector vectorA(vectorAx, vectorAy, vectorAz);
    Vector vectorB(vectorBx, vectorBy, vectorBz);

    if (VecFun == "Add") {
        Vector vectorO = vectorA.Add(vectorB);
        fpOutput = fopen("output.txt", "w");
        fprintf(fpOutput, "%.f %.f %.f", vectorO.x, vectorO.y, vectorO.z);
        fclose(fpOutput);
    }
    else if (VecFun == "Dot") {
        fpOutput = fopen("output.txt", "w");
        fprintf(fpOutput, "%.f", vectorA.DotProduct(vectorB));
        fclose(fpOutput);
    }
    else {
        printf("Invalid input.. (%s)\n", VecFun);
    }

    return 0;
}

input.txt:

Add
1 2 3
4 5 6

ouput.txt:

5 7 9

input.txt:

Dot
1 2 3
4 5 6

ouput.txt:

32

However, the if condition did not work, so I tried debugging with:

printf("Invalid input.. (%s)\n", VecFun);

and found this result:

enter image description here

Why are these results coming out? Also, how can I modify the if condition to work?

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Keastmin
  • 85
  • 6
  • 1
    Don't add the C tag tonC++ code unless you really like downvotes. – Jonathan Leffler Apr 05 '22 at 09:28
  • I`m sorry. I didn't think about it properly. – Keastmin Apr 05 '22 at 09:31
  • Please, have a look at [fgets()](https://en.cppreference.com/w/c/io/fgets): _Parsing stops if a newline character is found, in which case **str will contain that newline character**_. Have a look where your `)` appears. This is an indicator that your `VecFun` contains `"Add\n"` but not `"Add"` as you might expect (and that's not the same). (Btw. it was clever to delimit the output of your (wrong) input by braces. This is a trick I use always when reporting strings with arbitrary characters. Issues like your can hit one unexpectedly and the delimiters uncover this.) ;-) – Scheff's Cat Apr 05 '22 at 09:31
  • why are you not using an `ifstream` to read from the file? Using C io in C++ is making this code unecessarily complicated – 463035818_is_not_an_ai Apr 05 '22 at 09:44
  • The reason is because of the stability error, so I was forced to write it like that. – Keastmin Apr 05 '22 at 09:49

1 Answers1

1

You can't compare C-style strings for equality using the == operator. In code like if (VecFun == "Add"), both the VecFun variable (the name of a char array) and the "Add" (a string literal) decay to pointers to their first elements; and, since they are different items in different memory locations, that test will always result in a false value.

In C, you would need to use the strcmp function, as shown in the answer(s) to the question linked above. However, in C++ (since C++14), you can specify your literals as std::string objects, using the s suffix; then, tests like VecFun == "Add"s will work as expected.1

Here's a short demo:

#include <iostream>
#include <string>
using namespace std::string_literals;

int main()
{
    char test[10] = "Add";
    // Wrong - comparing two different pointers ...
    if (test == "Add") {
        std::cout << "Raw comparison succeeded!\n";
    }
    else {
        std::cout << "Raw comparison failed!\n";
    }
    // Plain "C" way, using the strcmp function ...
    if (strcmp(test, "Add") == 0) {
        std::cout << "strcmp comparison succeeded!\n";
    }
    else {
        std::cout << "strcmp comparison failed!\n";
    }
    // C++ way, using std::string literals ...
    if (test == "Add"s) {
        std::cout << "std::string comparison succeeded!\n";
    }
    else {
        std::cout << "std::string comparison failed!\n";
    }
    return 0;
}

1 If your compiler doesn't support the C++14 Standard or string literal operators, you could construct a std::string object explicily from the literal(s), using expressions like std::string("Add") in place of the "Add"s.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • Note also that, as mentioned in the comments on your question, you will need to address the fact that the `fgets` function will leave the trailing newline character in the string it returns. – Adrian Mole Apr 05 '22 at 10:33
  • ```if (!strcmp(VecFun, "Add"))``` I changed the code in this way, but there is another problem. I don't know how to prevent a string from containing a newline character. – Keastmin Apr 05 '22 at 10:39
  • @Keastmin Then add a newline to the end of the test literal: `"Add\n"` – Adrian Mole Apr 05 '22 at 10:43
  • I tried ```if (!strcmp(VecFun, "Add\n"))```, ```if (strcmp(VecFun, "Add\n") == 0)```, ```if (strcmp(VecFun, "Add\n"))``` , ```if (!strcmp(VecFun, "Add"))```. But all skip 'if' and 'else' works. In the txt file, I wrote Add well. – Keastmin Apr 05 '22 at 10:54
  • @Keastmin Have you tried setting the fourth character of your input to the nul terminator **before** the tests: `VecFun[3] = 0;`? (But then don't include the `\n` in the literal!) – Adrian Mole Apr 05 '22 at 11:00
  • ```char VecFun[10];```, ```char VecFun[10] = {};```, ```char VecFun[10] = "";``` I tested these three things. But the results were the same. – Keastmin Apr 05 '22 at 11:04
  • Add the `VecFun[3] = 0;` line after you have read the line from the input.txt. You also have issues in your code when scanning the 6 numbers, because the "Add" line will be in the way. Read that line first, then do the two scanf reads. All in the same opening session: no need to close then reopen the file. – Adrian Mole Apr 05 '22 at 11:16