如何用C语言从文本文件中读取虚拟数据

1hdlvixo  于 2022-12-03  发布在  其他
关注(0)|答案(2)|浏览(121)

我无法从文本文件中读取虚构数据。这是我的.txt文件
abc.txt

0.2e-3+0.3*I   0.1+0.1*I
0.3+0.1*I      0.1+0.4*I

我想把这些数据读入一个 * 矩阵 * 并打印出来。
我使用 C++herehere找到了解决方案。我不知道如何在C中做同样的事情。
我可以读取.txt中的小数和整数数据并打印它们。我还可以使用complex.h头打印在声明中初始化的虚数据。这是我编写的程序。

#include<stdio.h>
#include<stdlib.h>
#include<complex.h>
#include<math.h>
int M,N,i,j,k,l,p,q;
int b[2];
int main(void)
{
    FILE* ptr = fopen("abc.txt", "r");
        if (ptr == NULL) {
            printf("no such file.");
            return 0;
        }
    long double d=0.2e-3+0.3*I;
    long double c=0.0000000600415046630252;
    double matrixA[2][2];
    for(i=0;i<2; i++)
        for(j=0;j<2; j++)
            fscanf(ptr,"%lf+i%lf\n", creal(&matrixA[i][j]), cimag(&matrixA[i][j])); 
            //fscanf(ptr, "%lf", &matrixA[i][j]) for reading non-imainary data, It worked. 

    for(i=0;i<2; i++)
            for(j=0;j<2; j++)
                printf("%f+i%f\n", creal(matrixA[i][j]), cimag(matrixA[i][j]));
              //printf("%lf\n", matrixA[i][j]);  for printing non-imainary data, It worked. 

    printf("%f+i%f\n", creal(d), cimag(d));
    printf("%Lg\n",c);

    fclose(ptr);

    return 0;
}

但是我想从文本中读取它,因为我有一个更大的数组,我不能在声明时初始化,因为它的大小。

qxsslcnc

qxsslcnc1#

您的程式码有两个主要问题:

  • 您需要将complex添加到保存复数值的变量中。
  • scanf()需要指向对象的 * 指针 * 来存储扫描值。但是creal()返回一个值,从它的参数内容复制而来。它既不是指针,也不能获得复杂参数相应部分的地址。

因此,您需要提供缓存对象给scanf(),它会接收扫描的值。成功扫描后,这些值会结合成一个复杂的值,并指派给索引矩阵储存格。
未导致核心问题的次要问题包括:

  • 给定的源代码中增加了不需要的#include、未使用的变量、全局变量和常数实验,我将它们全部删除以查看真实的的内容。
  • 说明符"%f"(和其他许多说明符一样)允许scanf()跳过空格、制表符、换行符等空格。提供"\n"通常会造成比预期更大的危害。

我保留了"*I"来检查正确的格式。但是,只有在下一次调用scanf()时才会发现错误,当时它无法扫描下一个数字。

  • 你需要检查scanf()的返回值,总是!它返回成功转换的次数。
  • 让编译器计算数组中元素的个数是一个常见的好习惯。

sizeof是一个运算符,不是函数。

  • 最好向调用者返回符号值,而不是幻数。幸运的是,标准库定义了这些EXIT_...宏。
  • 符号已经被scanf()正确处理了。没有必要告诉它更多。但是为了用printf()得到一个好的输出,你可以用"+"作为一个标志来总是输出一个符号。
  • 由于符号现在直接放在数字前面,我把乘以I(如果你愿意,可以把它改成小写)的乘法移到虚部后面,这也符合输入格式。
  • 错误输出是通过stderr而不是stdout完成的。例如,这使您能够将标准输出重定向到文件管道,而不会丢失潜在的错误。您也可以将错误重定向到其他地方。这是一个众所周知的和受欢迎的标准。

这是一个可能的解决方案:

#include <stdio.h>
#include <stdlib.h>
#include <complex.h>

int main(void)
{
    FILE* ptr = fopen("abc.txt", "r");
    if (ptr == NULL) {
        perror("\"abc.txt\"");
        return EXIT_FAILURE;
    }

    double complex matrixA[2][2];

    for (size_t i = 0; i < sizeof matrixA / sizeof matrixA[0]; i++)
        for (size_t j = 0; j < sizeof matrixA[0] / sizeof matrixA[0][0]; j++) {
            double real;
            double imag;
            if (fscanf(ptr, "%lf%lf*I", &real, &imag) != 2) {
                fclose(ptr);
                fprintf(stderr, "Wrong input format\n");
                return EXIT_FAILURE;
            }
            matrixA[i][j] = real + imag * I;
        }

    fclose(ptr);

    for (size_t i = 0; i < sizeof matrixA / sizeof matrixA[0]; i++)
        for (size_t j = 0; j < sizeof matrixA[0] / sizeof matrixA[0][0]; j++)
            printf("%+f%+f*I\n", creal(matrixA[i][j]), cimag(matrixA[i][j]));
    return EXIT_SUCCESS;
}
b5buobof

b5buobof2#

这里有一个简单的解决方案,使用scanf()和示例中显示的格式。它以读取值的相同格式写入值--程序可以将输出扫描为输入。

/* SO 7438-4793 */
#include <stdio.h>

static int read_complex(FILE *fp, double *r, double *i)
{
    int offset = 0;
    char sign[2];
    if (fscanf(fp, "%lg%[-+]%lg*%*[iI]%n", r, sign, i, &offset) != 3 || offset == 0)
        return EOF;
    if (sign[0] == '-')
        *i = -*i;
    return 0;
}

int main(void)
{
    double r;
    double i;

    while (read_complex(stdin, &r, &i) == 0)
        printf("%g%+g*I\n", r, i);

    return 0;
}

样品输入:

0.2e-3+0.3*I   0.1+0.1*I
0.3+0.1*I      0.1+0.4*I
-1.2-3.6*I     -6.02214076e23-6.62607015E-34*I

样本输入的输出:

0.0002+0.3*I
0.1+0.1*I
0.3+0.1*I
0.1+0.4*I
-1.2-3.6*I
-6.02214e+23-6.62607e-34*I

最后指数较大的数字是阿伏伽德罗数和普朗克常数。
该格式与scanf()的格式一样严格,但是,尽管它需要一个符号(+-),并且要求*I紧跟在虚部之后(如果缺少*I,转换将失败),并接受iI来表示虚部值:

  • 它不会阻止虚数具有第二个符号(因此它将读取诸如“-6+-4*I“的值)。
  • 它并没有停止在强制符号后面有白色(所以它将读取一个值,如“-6+ 24*I“)。
  • 这并不能阻止真实的部在一行虚部在下一行.
  • 它不能正确处理纯实数或纯虚数。

scanf()函数对白色的处理非常灵活,很难阻止它们接受空格,这需要一个自定义的解析器来阻止不需要的空格,可以通过将数字和标记分别作为字符串读取来实现,然后验证是否没有空格等等。这可能是处理它的最好方法。在确保没有空格之后,您可以使用sscanf()来转换字符串read。s没有嵌入白色,但格式正确。
我不知道您使用的是哪种IDE的C,所以我不理解这个./testprog <test.data
我还没有找到一个不会让我发疯的IDE。我使用的是在终端窗口中运行的Unix shell。假设程序名为testprog,数据文件为test.data,键入./testprog < test.data将运行该程序,并将test.data的内容作为其标准输入。在Windows上,这将是一个命令窗口(我认为PowerShell的工作方式也大致相同)。
我用fgets读取了文本文件的每一行,虽然我知道sscanf的功能,但我不知道如何解析一整行,每行大约有23个元素,如果一行元素的数量很少,我知道如何解析,你能帮我吗?
正如我在注解中提到的,SOQ & Ax 1 e0f1x解释了如何使用sscanf()从一行中读取多个条目。在这种情况下,您将需要从一行中读取多个复数。下面是一些代码,展示了它的工作情况。它使用POSIX getline()函数读取任意长的行。如果您不能使用它,您可以使用fgets(),但是需要预先分配一个足够大的行缓冲区。

#include <stdio.h>
#include <stdlib.h>
#include <complex.h>

#ifndef CMPLX
#define CMPLX(r, i)     ((double complex)((double)(r) + I * (double)(i)))
#endif

static size_t scan_multi_complex(const char *string, size_t nvalues,
                                 complex double *v, const char **eoc)
{
    size_t nread = 0;
    const char *buffer = string;
    while (nread < nvalues)
    {
        int offset = 0;
        char sign[2];
        double r, i;
        if (sscanf(buffer, "%lg%[-+]%lg*%*[iI]%n", &r, sign, &i, &offset) != 3 || offset == 0)
            break;
        if (sign[0] == '-')
            i = -i;
        v[nread++] = CMPLX(r, i);
        buffer += offset;
    }

    *eoc = buffer;
    return nread;
}

static void dump_complex(size_t nvalues, complex double values[nvalues])
{
    for (size_t i = 0; i < nvalues; i++)
        printf("%g%+g*I\n", creal(values[i]), cimag(values[i]));
}

enum { NUM_VALUES = 128 };

int main(void)
{
    double complex values[NUM_VALUES];
    size_t nvalues = 0;
    char *buffer = 0;
    size_t buflen = 0;
    int length;
    size_t lineno = 0;

    while ((length = getline(&buffer, &buflen, stdin)) > 0 && nvalues < NUM_VALUES)
    {
        const char *eoc;
        printf("Line: %zu [[%.*s]]\n", ++lineno, length - 1, buffer);
        size_t nread = scan_multi_complex(buffer, NUM_VALUES - nvalues, &values[nvalues], &eoc);
        if (*eoc != '\0' && *eoc != '\n')
            printf("EOC:  [[%s]]\n", eoc);
        if (nread == 0)
            break;
        dump_complex(nread, &values[nvalues]);
        nvalues += nread;
    }
    free(buffer);

    printf("All done:\n");
    dump_complex(nvalues, values);

    return 0;
}

下面是一个8行的数据文件,每行包含10个复数):

-1.95+11.00*I +21.72+64.12*I -95.16-1.81*I +64.23+64.55*I +28.42-29.29*I -49.25+7.87*I +44.98+79.62*I +69.80-1.24*I +61.99+37.01*I +72.43+56.88*I
-9.15+31.41*I +63.84-15.82*I -0.77-76.80*I -85.59+74.86*I +93.00-35.10*I -93.82+52.80*I +85.45+82.42*I +0.67-55.77*I -58.32+72.63*I -27.66-81.15*I
+87.97+9.03*I +7.05-74.91*I +27.60+65.89*I +49.81+25.08*I +44.33+77.00*I +93.27-7.74*I +61.62-5.01*I +99.33-82.80*I +8.83+62.96*I +7.45+73.70*I
+40.99-12.44*I +53.34+21.74*I +75.77-62.56*I +54.16-26.97*I -37.02-31.93*I +78.20-20.91*I +79.64+74.71*I +67.95-40.73*I +58.19+61.25*I +62.29-22.43*I
+47.36-16.19*I +68.48-15.00*I +6.85+61.50*I -6.62+55.18*I +34.95-69.81*I -88.62-81.15*I +75.92-74.65*I +85.17-3.84*I -37.20-96.98*I +74.97+78.88*I
+56.80+63.63*I +92.83-16.18*I -11.47+8.81*I +90.74+42.86*I +19.11-56.70*I -77.93-70.47*I +6.73+86.12*I +2.70-57.93*I +57.87+29.44*I +6.65-63.09*I
-35.35-70.67*I +8.08-21.82*I +86.72-93.82*I -28.96-24.69*I +68.73-15.36*I +52.85+94.65*I +85.07-84.04*I +9.98+29.56*I -78.01-81.23*I -10.67+13.68*I
+83.10-33.86*I +56.87+30.23*I -78.56+3.73*I +31.41+10.30*I +91.98+29.04*I -9.20+24.59*I +70.82-19.41*I +29.21+84.74*I +56.62+92.29*I +70.66-48.35*I

程序的输出为:

Line: 1 [[-1.95+11.00*I +21.72+64.12*I -95.16-1.81*I +64.23+64.55*I +28.42-29.29*I -49.25+7.87*I +44.98+79.62*I +69.80-1.24*I +61.99+37.01*I +72.43+56.88*I]]
-1.95+11*I
21.72+64.12*I
-95.16-1.81*I
64.23+64.55*I
28.42-29.29*I
-49.25+7.87*I
44.98+79.62*I
69.8-1.24*I
61.99+37.01*I
72.43+56.88*I
Line: 2 [[-9.15+31.41*I +63.84-15.82*I -0.77-76.80*I -85.59+74.86*I +93.00-35.10*I -93.82+52.80*I +85.45+82.42*I +0.67-55.77*I -58.32+72.63*I -27.66-81.15*I]]
-9.15+31.41*I
63.84-15.82*I
-0.77-76.8*I
-85.59+74.86*I
93-35.1*I
-93.82+52.8*I
85.45+82.42*I
0.67-55.77*I
-58.32+72.63*I
-27.66-81.15*I
Line: 3 [[+87.97+9.03*I +7.05-74.91*I +27.60+65.89*I +49.81+25.08*I +44.33+77.00*I +93.27-7.74*I +61.62-5.01*I +99.33-82.80*I +8.83+62.96*I +7.45+73.70*I]]
87.97+9.03*I
7.05-74.91*I
27.6+65.89*I
49.81+25.08*I
44.33+77*I
93.27-7.74*I
61.62-5.01*I
99.33-82.8*I
8.83+62.96*I
7.45+73.7*I
Line: 4 [[+40.99-12.44*I +53.34+21.74*I +75.77-62.56*I +54.16-26.97*I -37.02-31.93*I +78.20-20.91*I +79.64+74.71*I +67.95-40.73*I +58.19+61.25*I +62.29-22.43*I]]
40.99-12.44*I
53.34+21.74*I
75.77-62.56*I
54.16-26.97*I
-37.02-31.93*I
78.2-20.91*I
79.64+74.71*I
67.95-40.73*I
58.19+61.25*I
62.29-22.43*I
Line: 5 [[+47.36-16.19*I +68.48-15.00*I +6.85+61.50*I -6.62+55.18*I +34.95-69.81*I -88.62-81.15*I +75.92-74.65*I +85.17-3.84*I -37.20-96.98*I +74.97+78.88*I]]
47.36-16.19*I
68.48-15*I
6.85+61.5*I
-6.62+55.18*I
34.95-69.81*I
-88.62-81.15*I
75.92-74.65*I
85.17-3.84*I
-37.2-96.98*I
74.97+78.88*I
Line: 6 [[+56.80+63.63*I +92.83-16.18*I -11.47+8.81*I +90.74+42.86*I +19.11-56.70*I -77.93-70.47*I +6.73+86.12*I +2.70-57.93*I +57.87+29.44*I +6.65-63.09*I]]
56.8+63.63*I
92.83-16.18*I
-11.47+8.81*I
90.74+42.86*I
19.11-56.7*I
-77.93-70.47*I
6.73+86.12*I
2.7-57.93*I
57.87+29.44*I
6.65-63.09*I
Line: 7 [[-35.35-70.67*I +8.08-21.82*I +86.72-93.82*I -28.96-24.69*I +68.73-15.36*I +52.85+94.65*I +85.07-84.04*I +9.98+29.56*I -78.01-81.23*I -10.67+13.68*I]]
-35.35-70.67*I
8.08-21.82*I
86.72-93.82*I
-28.96-24.69*I
68.73-15.36*I
52.85+94.65*I
85.07-84.04*I
9.98+29.56*I
-78.01-81.23*I
-10.67+13.68*I
Line: 8 [[+83.10-33.86*I +56.87+30.23*I -78.56+3.73*I +31.41+10.30*I +91.98+29.04*I -9.20+24.59*I +70.82-19.41*I +29.21+84.74*I +56.62+92.29*I +70.66-48.35*I]]
83.1-33.86*I
56.87+30.23*I
-78.56+3.73*I
31.41+10.3*I
91.98+29.04*I
-9.2+24.59*I
70.82-19.41*I
29.21+84.74*I
56.62+92.29*I
70.66-48.35*I
All done:
-1.95+11*I
21.72+64.12*I
-95.16-1.81*I
64.23+64.55*I
28.42-29.29*I
-49.25+7.87*I
44.98+79.62*I
69.8-1.24*I
61.99+37.01*I
72.43+56.88*I
-9.15+31.41*I
63.84-15.82*I
-0.77-76.8*I
-85.59+74.86*I
93-35.1*I
-93.82+52.8*I
85.45+82.42*I
0.67-55.77*I
-58.32+72.63*I
-27.66-81.15*I
87.97+9.03*I
7.05-74.91*I
27.6+65.89*I
49.81+25.08*I
44.33+77*I
93.27-7.74*I
61.62-5.01*I
99.33-82.8*I
8.83+62.96*I
7.45+73.7*I
40.99-12.44*I
53.34+21.74*I
75.77-62.56*I
54.16-26.97*I
-37.02-31.93*I
78.2-20.91*I
79.64+74.71*I
67.95-40.73*I
58.19+61.25*I
62.29-22.43*I
47.36-16.19*I
68.48-15*I
6.85+61.5*I
-6.62+55.18*I
34.95-69.81*I
-88.62-81.15*I
75.92-74.65*I
85.17-3.84*I
-37.2-96.98*I
74.97+78.88*I
56.8+63.63*I
92.83-16.18*I
-11.47+8.81*I
90.74+42.86*I
19.11-56.7*I
-77.93-70.47*I
6.73+86.12*I
2.7-57.93*I
57.87+29.44*I
6.65-63.09*I
-35.35-70.67*I
8.08-21.82*I
86.72-93.82*I
-28.96-24.69*I
68.73-15.36*I
52.85+94.65*I
85.07-84.04*I
9.98+29.56*I
-78.01-81.23*I
-10.67+13.68*I
83.1-33.86*I
56.87+30.23*I
-78.56+3.73*I
31.41+10.3*I
91.98+29.04*I
-9.2+24.59*I
70.82-19.41*I
29.21+84.74*I
56.62+92.29*I
70.66-48.35*I

该代码可以处理一行中包含任意数量条目的行(由于复数数组大小的限制,总共最多128个条目),但这也可以是固定的。

相关问题