3

i want to read an array of complex numbers (in a+bi form). There are several suggestions I found on the internet, however those methods only result the real part, while the imaginary part is always 0. And infact the real part of the next number is the imaginary of the previous number.

For example, I have an text file as follow:

2+4i
1+5i
7+6i

And here is a suggestion for reading complex data

int nRow = 3;
std::complex<int> c;
std::ifstream fin("test.txt");
std::string line;
std::vector<std::complex<int> > vec;
vec.reserve(nRow);
while (std::getline(fin, line))
{
    std::stringstream stream(line);
    while (stream >> c)
    {
        vec.push_back(c);
    }
}

for (int i = 0; i < nRow; i++){
    cout << vec[i].real() << "\t" << vec[i].imag() << endl;
}

while (1);
return 0;

And the output result is:

2   0
4   0
1   0

Is there a proper way to read a+bi complex numbers from text file? Or do I have to read the data as a string, and then process the string to extract and convert it back to complex numer?

Thanks !

BL_
  • 821
  • 1
  • 17
  • 23

4 Answers4

4

One option is to read separately the real and imaginary part in 2 ints, and the sign into a char, then emplace_back into the complex vector, like

int re, im;
char sign;
while (stream >> re >> sign >> im)
{
    vec.emplace_back(re, (sign == '-') ? -im : im);
}

Here sign is a char variable that "eats" up the sign.

vsoftco
  • 55,410
  • 12
  • 139
  • 252
2
FILE *fp;
char line[80];
int a, b;

if ((fp = fopen("filename", "r") != NULL)
    while (fgets(line, 80, fp) != NULL) {
        if (sscanf(line, "%d + %di", &a, &b) == 2)
            /* do something with a and b */
        else
            fprintf(stderr, "Not in a+bi form");
    }
lost_in_the_source
  • 10,998
  • 9
  • 46
  • 75
2

Your requirement (the format of input you seek) does not correspond to the method you are using to read it. The default streaming of a complex is the real and the imaginary part separated by spaces and in brackets - the sign between is not mandatory, and the trailing i is not required.

The obvious way to parse for input you seek is to read the real part, read a character, check if the character is a signed (+ or -) and ignore spaces, then read the imaginary part. That is trivial with istreams.

Peter
  • 35,646
  • 4
  • 32
  • 74
  • thank @Peter. You're right, the format was not suitable for the method I used. I'll look at {istream} function. By the way, I think the above answer from vsoftco may use a similar method like your suggestion. – BL_ Jan 07 '16 at 12:59
1
int real[10] = { 0 };
int imaginary[10] = { 0 };
FILE *lpFile = fopen("filename" "rt"); // Open the file
for (int i = 0; i < 10; i++) {
    fscanf(lpFile, "%d+%di", &real[i], &imaginary[i]); // Read data 10 times
}
fclose(lpFile); // Close the file

This example code will read 10 complex numbers from a file.