无法弄清楚如何隔离和替换数字

时间:2019-11-28 20:50:24

标签: c scanf readfile data-manipulation fgetc

我所做的是使用第一组代码提取了数据并将其放入新文件中,因此只有值

这是我输入的第一组代码文件:

original input

这是第二组代码的输入文件,这是我的主要问题:

second set of input code

然后在第二组代码中是读取新文件的位置,因此它将使用fgetc输出数字,我现在该如何使用一个简单的公式呢? 具体来说,公式会将任何10的值变成0的值 我尝试过,因为fgetc是无符号字符,所以我尝试在if语句中使用10的二进制数

这是到目前为止的代码:

#include<stdio.h> 

int main() 
{ 
    FILE* ptr = fopen("Data.txt","r"); 
    if (ptr==NULL) 
    { 
        printf("no such file."); 
        return 0; 
    } 

    FILE*fp = fopen("/data flow/NEWdata.txt", "w+");

        int x;
  int count=0;
    char buf[100];
    fscanf(ptr,"%*s %*s %*s %*s %*s %*s %*s %s ",buf); //skip first line and stuff before first value(column names)
    while (fscanf(ptr,"%*s %*s %*s %*s %s  ",buf)==1) 
    {

        fprintf(fp, "%s\n",buf);
    }
    fclose(fp); 
    return 0; 
} 

第二组代码

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

int main () {
   FILE *fp;
   char str[100];

   /* opening file for reading */
   fp = fopen("NEWdata.txt" , "r");
   if(fp == NULL) {
      perror("Error opening file");
      return(-1);
   }
   int i;
   while( fgets (str, 100, fp)!=NULL ) {
      /* writing content to stdout */
      sscanf (str,%u,i);
    printf(%u,i);

   }
   fclose(fp);

   return(0);
}

我的命令行 enter image description here

我收到的错误低于 enter image description here

 if (measure = 10)
            fprintf (ofp, "%f\n", measure - 10);
        else
            fprintf (ofp, "%f\n", measure);
#include <stdio.h>

#define MAXC 1024       /* if you need a constant, #define one (or more) */
#define MAXF   32

int main (int argc, char **argv) {

    char buf[MAXC];     /* buffer to hold each line read from file */
    size_t n = 0;       /* line counter */
   FILE *fp, *ofp;     /* file pointer, output file pointer */

    if (argc < 3 ) {    /* validate 2 arguments given for in/out filenames */
        fprintf (stderr, "error: insufficient input,\n"
                         "usage: %s filename outfilename\n", argv[0]);
        return 1;
    }

    /* open file/validate file open for reading */
    if ((fp = fopen ("Data.txt", "r")) == NULL) {
        perror ("fopen-argv[1]");
        return 1;
    }

    if ((ofp = fopen ("NEWdata.txt", "w")) == NULL) {
        perror ("fopen-argv[2]");
        return 1;
    }

    if (!fgets (buf, MAXC, fp)) {   /* read/discard 1st line */
        fputs ("error: EOF on read of first line.\n", stderr);
        return 1;
    }

    while (fgets (buf, MAXC, fp)) { /* read all remaining lines */
        char date[MAXF], time[MAXF], prod[MAXF], unit[MAXF];
        double measure;

        if (sscanf (buf, "%s %s %s %lf %s", /* validate all 5 fields */
                    date, time, prod, &measure, unit) != 5) {
            fprintf (stderr, "error: invalid format, line: %zu\n", n + 1);
            continue;
        }

        /* do whatever you need with the separated values.
         * if measure is 10.xx, then make measure 0.xx
         */
        if (measure = 10)
            fprintf (ofp, "%f\n", measure - 10);
        else
            fprintf (ofp, "%f\n", measure);

        n++;    /* increment line counter */
    }
}

1 个答案:

答案 0 :(得分:1)

如果我理解正确,并且您想从Data.txt中读取值,并且如果Measurement的值为10,则希望将值设置为0 。如我的评论所述,您的Measurement值是一个浮点数(下面使用double)。由于不能完全以 floating-point 格式表示所有数字,因此浮点数的比较本质上是不精确的。 (10.0可以准确表示,但要注意限制)。参见Is floating point math broken?Why Are Floating Point Numbers Inaccurate?

在到达该位置之前,请避免硬编码文件名或在代码中使用 Magic-Numbers main()带有允许您将信息传递给代码的参数。您可以简单地将文件名传递为程序的第一个参数,也可以将文件名作为输入。例如

#include <stdio.h>

#define MAXC 1024       /* if you need a constant, #define one (or more) */
#define MAXF   32

int main (int argc, char **argv) {

    char buf[MAXC];     /* buffer to hold each line read from file */
    size_t n = 0;       /* line counter */
    FILE *fp;           /* file pointer */

    if (argc < 2 ) {    /* validate 1 argument given for filename */
        fprintf (stderr, "error: insufficient input,\n"
                         "usage: %s filename\n", argv[0]);
        return 1;
    }

    /* open file/validate file open for reading */
    if ((fp = fopen (argv[1], "r")) == NULL) {
        perror ("fopen-argv[1]");
        return 1;
    }

使用fgets()和缓冲区(例如MAXC的字符数组,最大字符),您可以读取和丢弃第一行。 (*不要忘记 验证 所读内容):

    if (!fgets (buf, MAXC, fp)) {   /* read/discard 1st line */
        fputs ("error: EOF on read of first line.\n", stderr);
        return 1;
    }

现在,只需循环将带有fgets()的每一行读入同一缓冲区,然后将该缓冲区传递到sscanf()即可从该行中解析所需的值,例如

    while (fgets (buf, MAXC, fp)) { /* read all remaining lines */
        char date[MAXF], time[MAXF], prod[MAXF], unit[MAXF];
        double measure;

        if (sscanf (buf, "%s %s %s %lf %s", /* validate all 5 fields */
                    date, time, prod, &measure, unit) != 5) {
            fprintf (stderr, "error: invalid format, line: %zu\n", n + 1);
            continue;
        }

注意:如果该行的格式不正确,您的读取不会像使用fscanf()那样失败。在这里,使用fgets()进行读取会消耗一个-line,一次,不考虑格式,然后使用sscanf()来解析该行中的值。如果该行格式与您的 format-string 不匹配,则只需丢弃该行然后阅读下一行。)

现在,您可以对date, time, prod, measure & unit中的值进行任何操作。在这里,我们将简单地比较measure以查看它是10.0还是大于11.0(不包括在内),并从构成值{{1的值中减去10.0 }} 0.xxx所在的位置。如果愿意,您可以简单地输出10.xxx

0.0

这是您想要的一个简单示例。 (1)用 /* do whatever you need with the separated values. * if measure is 10.xx, then make measure 0.xx */ if (10.0 <= measure && measure < 11.0) printf ("measurement[%2zu]: %.3f (was %.3f)\n", n, measure - 10., measure); else printf ("measurement[%2zu]: %.3f\n", n, measure); n++; /* increment line counter */ } } 读取和(2)用fgets()解析的基本原理可以涵盖各种输入情况。您将反复使用它。这样做而不是直接使用sscanf()的原因是为了防止出现单行格式错误,从而导致 matching-failure (匹配失败),该错误会导致从输入流中提取字符而不再将有问题的字符留在输入流 未读 ,只是在下次尝试输入时再次咬你。

完整的示例是:

fscanf()

示例输入文件

#include <stdio.h>

#define MAXC 1024       /* if you need a constant, #define one (or more) */
#define MAXF   32

int main (int argc, char **argv) {

    char buf[MAXC];     /* buffer to hold each line read from file */
    size_t n = 0;       /* line counter */
    FILE *fp;           /* file pointer */

    if (argc < 2 ) {    /* validate 1 argument given for filename */
        fprintf (stderr, "error: insufficient input,\n"
                         "usage: %s filename\n", argv[0]);
        return 1;
    }

    /* open file/validate file open for reading */
    if ((fp = fopen (argv[1], "r")) == NULL) {
        perror ("fopen-argv[1]");
        return 1;
    }

    if (!fgets (buf, MAXC, fp)) {   /* read/discard 1st line */
        fputs ("error: EOF on read of first line.\n", stderr);
        return 1;
    }

    while (fgets (buf, MAXC, fp)) { /* read all remaining lines */
        char date[MAXF], time[MAXF], prod[MAXF], unit[MAXF];
        double measure;

        if (sscanf (buf, "%s %s %s %lf %s", /* validate all 5 fields */
                    date, time, prod, &measure, unit) != 5) {
            fprintf (stderr, "error: invalid format, line: %zu\n", n + 1);
            continue;
        }

        /* do whatever you need with the separated values.
         * if measure is 10.xx, then make measure 0.xx
         */
        if (10.0 <= measure && measure < 11.0)
            printf ("measurement[%2zu]: %.3f   (was %.3f)\n",
                    n, measure - 10., measure);
        else
            printf ("measurement[%2zu]: %.3f\n", n, measure);

        n++;    /* increment line counter */
    }
}

使用/输出示例

下面,我显示$ cat dat/data_timestamp.txt TimeDateStamp Product Measurement Unit 2019-11-09 16:54 FS2012 0.344 SLPM 2019-11-09 16:54 FS2012 0.344 SLPM 2019-11-09 16:54 FS2012 0.344 SLPM 2019-11-09 16:54 FS2012 0.344 SLPM 2019-11-09 16:54 FS2012 0.136 SLPM 2019-11-09 16:54 FS2012 0.136 SLPM 2019-11-09 16:54 FS2012 0.136 SLPM 2019-11-09 16:54 FS2012 0.136 SLPM 2019-11-09 16:54 FS2012 0.047 SLPM 2019-11-09 16:54 FS2012 0.047 SLPM 2019-11-09 16:54 FS2012 0.047 SLPM 2019-11-09 16:54 FS2012 0.047 SLPM 2019-11-09 16:54 FS2012 1.991 SLPM 2019-11-09 16:54 FS2012 1.991 SLPM 2019-11-09 16:54 FS2012 1.991 SLPM 2019-11-09 16:54 FS2012 10.0 SLPM 2019-11-09 16:54 FS2012 10.661 SLPM 2019-11-09 16:54 FS2012 10.991 SLPM 2019-11-09 16:54 FS2012 11.0 SLPM 减少到10的位置:

0

仔细检查一下,让我知道这是否接近您的需求。我可能仍会误解您尝试从$ ./bin/read_data_timestamp dat/data_timestamp.txt measurement[ 0]: 0.344 measurement[ 1]: 0.344 measurement[ 2]: 0.344 measurement[ 3]: 0.344 measurement[ 4]: 0.136 measurement[ 5]: 0.136 measurement[ 6]: 0.136 measurement[ 7]: 0.136 measurement[ 8]: 0.047 measurement[ 9]: 0.047 measurement[10]: 0.047 measurement[11]: 0.047 measurement[12]: 1.991 measurement[13]: 1.991 measurement[14]: 1.991 measurement[15]: 0.000 (was 10.000) measurement[16]: 0.661 (was 10.661) measurement[17]: 0.991 (was 10.991) measurement[18]: 11.000 10所要实现的目标,但是如果我误解了,很高兴为您提供进一步的帮助,请在下面发表评论。

写输出文件作为程序的第二个论点

要将调整后的0值单独写入所选的输出文件,您只需在命令行中输入文件名后提供要使用的输出文件名,然后使用{ {1}}(您在Measurement的第二个命令行参数)更改很小。只需添加另一个argv[2]指针main()(用于输出文件指针),然后打开该文件以进行写入:

FILE*

然后仅使用ofp输出调整后的测量值,例如

    FILE *fp, *ofp;     /* file pointer, output file pointer */

    if (argc < 3 ) {    /* validate 2 arguments given for in/out filenames */
        fprintf (stderr, "error: insufficient input,\n"
                         "usage: %s filename outfilename\n", argv[0]);
        return 1;
    }

    /* open file/validate file open for reading */
    if ((fp = fopen (argv[1], "r")) == NULL) {
        perror ("fopen-argv[1]");
        return 1;
    }

    if ((ofp = fopen (argv[2], "w")) == NULL) {
        perror ("fopen-argv[2]");
        return 1;
    }

(程序的其余部分完全相同)

fprintf

如果我随后用两个参数(例如输入和输出文件名)调用程序,则如下:

        if (10.0 <= measure && measure < 11.0)
            fprintf (ofp, "%.3f\n", measure - 10.);
        else
            fprintf (ofp, "%.3f\n", measure);

我将从输入文件#include <stdio.h> #define MAXC 1024 /* if you need a constant, #define one (or more) */ #define MAXF 32 int main (int argc, char **argv) { char buf[MAXC]; /* buffer to hold each line read from file */ size_t n = 0; /* line counter */ FILE *fp, *ofp; /* file pointer, output file pointer */ if (argc < 3 ) { /* validate 2 arguments given for in/out filenames */ fprintf (stderr, "error: insufficient input,\n" "usage: %s filename outfilename\n", argv[0]); return 1; } /* open file/validate file open for reading */ if ((fp = fopen (argv[1], "r")) == NULL) { perror ("fopen-argv[1]"); return 1; } if ((ofp = fopen (argv[2], "w")) == NULL) { perror ("fopen-argv[2]"); return 1; } if (!fgets (buf, MAXC, fp)) { /* read/discard 1st line */ fputs ("error: EOF on read of first line.\n", stderr); return 1; } while (fgets (buf, MAXC, fp)) { /* read all remaining lines */ char date[MAXF], time[MAXF], prod[MAXF], unit[MAXF]; double measure; if (sscanf (buf, "%s %s %s %lf %s", /* validate all 5 fields */ date, time, prod, &measure, unit) != 5) { fprintf (stderr, "error: invalid format, line: %zu\n", n + 1); continue; } /* do whatever you need with the separated values. * if measure is 10.xx, then make measure 0.xx */ if (10.0 <= measure && measure < 11.0) fprintf (ofp, "%.3f\n", measure - 10.); else fprintf (ofp, "%.3f\n", measure); n++; /* increment line counter */ } } 中读取并将结果写入输出文件$ ./bin/read_data_timestamp2 dat/data_timestamp.txt dat/measure_val.txt (您可以将任何所需的文件名用于输出文件,但输入内容为{{1} }。

生成的输出文件

dat/data_timestamp.txt

让我知道是否可以清除它。