简体   繁体   中英

reading a number of type double from a text file

I am still stuck on this problem, I have tried a lot of things to get it and still no success... All I am trying to do is read the number into one array and the letters into another. That way, I can call both at the same time to take a statistical analysis of the letter frequency of two books. I know how to do this for a string, but I want to only copy the input of the numbers, which are two spaces in front of the letter they represent. The code reads two files through the command prompt(argv[1] and argv[2]) and compares the two together take the root mean square(RMS) of the two as the output. Here is the code I have so far:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#define NUM_LETTERS 26
int main( int argc, char *argv[] )
{
    FILE *fp, *fp2;
    int ch, i, counter;
    double frequencysquared[NUM_LETTERS], freqone[NUM_LETTERS], freqtwo[NUM_LETTERS], average;
    fp = fopen(argv[1], "r");
    fp2 = fopen(argv[2], "r");
    while((ch=fgetc(fp)) != EOF)
    {
        freqone[ch] = fgets(/*unsure*/, 22, fp); 
    }
    while((ch=fgetc(fp2)) != EOF)
    {
        freqtwo[ch] = fgets(/*unsure*/, 22, fp2);
    }
    while(i=0; i<NUM_LETTERS; i++)
    {
        average += pow(( freqone[i]-freqtwo[i] ), 2);
    }
    average/=NUM_LETTERS;
    average = sqrt(average);
    printf("RMS Frequency: %lf", average);
    fclose(fp);
    fclose(fp2);
    return 0;
}

Text file:

A 0.08030130328545595500
B 0.01404566680148545800
C 0.02309245337888202900
D 0.04680329046987134100
E 0.12475974957130967000
F 0.02262448732647651800
G 0.02092142515718645500
H 0.06495870199587520900
I 0.06832638626586488900
J 0.00118328558965393900
K 0.00796545073487383260
L 0.03678714564106335500
M 0.02553256208071077300
N 0.07071134182580297900
O 0.07759211410349403600
P 0.01653257210855475400
Q 0.00111309068179311220
R 0.06200383063640040700
S 0.06269909448568859700
T 0.09005003894146078300
U 0.02792921679195900500
V 0.00865068674018190480
W 0.02356209073861756000
X 0.00115988728703366340
Y 0.02033479628434954300
Z 0.00035933107595423293

The rough outline of the program is on the right track, but you have many details wrong. For one, scanf can take care of getting the input. No need to fiddle with strings.

Also, you need much better error checking.

Here's a start:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define SIZE ('Z' - 'A' + 1)

void die(int err) {
  fprintf(stderr, "error %d\n", err);
  exit(err);
}

int main(int argc, char *argv[]) {
  char ch;
  double f, a[SIZE], b[SIZE];
  FILE *fa, *fb;

  if (argc != 3) die(1);
  fa = fopen(argv[1], "r");
  if (!fa) die(2);
  fb = fopen(argv[2], "r");
  if (!fb) die(3);
  for (int i = 0; i < SIZE; ++i)
    a[i] = b[i] = -1.0;
  while (fscanf(fa, " %c%lf", &ch, &f) == 2)
    if ('A' <= ch && ch <= 'Z') a[ch - 'A'] = f; else die(4);
  fclose(fa);
  while (fscanf(fb, " %c%lf", &ch, &f) == 2)
    if ('A' <= ch && ch <= 'Z') b[ch - 'A'] = f; else die(5);
  fclose(fb);
  double sum_d2 = 0;
  for (int i = 0; i < SIZE; ++i) {
    if (a[i] < 0 || b[i] < 0) die(100 + i);
    double d = a[i] - b[i];
    sum_d2 += d * d;
  }
  double rms = sqrt(sum_d2 / SIZE);
  printf("RMS Frequency: %f\n", rms);
  return 0;
}

Just do step at a time. Make the code as simple as possible. It is better to use a separate function to calculate the RMS , just because having everything in the main function can get overwhelming.

Here is some example code that will help you achieve your task:

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

#define NUMLETTERS 26

#define RMS_VALID 1
#define RMS_INVALID 0

double calc_rms(double X[], double Y[], int n, double *rms);
void read_file(double numbers[], char letters[], FILE *stream);

int 
main(int argc, char const *argv[]) {
    FILE *fp1, *fp2;
    double numbers1[NUMLETTERS], numbers2[NUMLETTERS];
    char letters1[NUMLETTERS], letters2[NUMLETTERS];
    double rms;

    fp1 = fopen(argv[1], "r");
    fp2 = fopen(argv[2], "r");
    if (fp1 == NULL || fp2 == NULL) {
        fprintf(stderr, "%s\n", "Error Reading a File");
        exit(EXIT_FAILURE);
    }

    read_file(numbers1, letters1, fp1);
    read_file(numbers2, letters2, fp2);

    if (calc_rms(numbers1, numbers2, NUMLETTERS, &rms) != RMS_INVALID) {
        printf("RMS Frequency: %f\n", rms);
    }

    return 0;
}

void
read_file(double numbers[], char letters[], FILE *stream) {
    double onedouble;
    char oneletter;
    int count = 0;

    while (fscanf(stream, " %c %lf", &oneletter, &onedouble) == 2) {
        numbers[count] = onedouble;
        letters[count] = oneletter;
        count++;
    }
}

double
calc_rms(double X[], double Y[], int n, double *rms) {
    int i;
    double sum = 0.0, diff;

    if (n <= 0) {
        return RMS_INVALID; // just for precaution
    }

    for (i = 0; i < n; i++) {
        diff = (X[i] - Y[i]);
        sum += diff * diff;
    }
    *rms = sqrt(sum/n);
    return RMS_VALID;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM