Member Avatar for jtbens01

I've searched google and tried several different things but I can't figure out how to read strings into a two dimensional character array and also read doubles into separate arrays all from the same text file. Please provide any help you can and let me know how you might accomplish this. Here is the data in the text file as it appears. The '7' is suppose to let us know how many metals are present and should be stored in the array. Thanks in advance!

7
aluminum .012580 .003000 32. 1130.
cast-iron .005441 .001747 32. 1160.
ingot-iron .006375 .001636 32. 1380.
malleable-iron .006503 .001622 32. 930.
ingot-steel .006212 .001623 32. 1380.
copper .009278 .001244 32. 1160.
nickel .007652 .001023 32. 1830.

This is one thing I tried

void getDatabase(char metals[][METALSTR], double aValues[], 
     double bValues[], double minTemp[], double maxTemp[],
     int *number) {
         
         char fileName[METALSTR]; // Assume the file name is 29 characters or less
         char metalName[35];
         int i = 0;
         
         printf("Enter metals database file name: ");
         scanf("%s", &fileName);
         
         FILE *inputFile = fopen(fileName, "r");
         
         if (inputFile == NULL) {
                       
                       printf("\nThe file specified is not valid.");
                       printf("\nThe program will now terminate.");
                       exit(0);
                       }
                       
         // Get the first number from the file which inidicates number of metals
         fscanf(inputFile, "%d", &number);
         printf("%d", number);
         
         // Loop through to the end of the file and store data in arrays
         
         while (fgetc(inFile) != EOF) != NULL) {
               
               
          fscanf(inputFile, "%s", &metalName);
          fscanf(inputFile, "%lf", aValues[i]);
          fscanf(inputFile, "%lf", bValues[i]);
          fscanf(inputFile, "%lf", minTemp[i]);
          fscanf(inputFile, "%lf", maxTemp[i]);
          
          printf("%s\n", metalName[i]);
          printf("%lf\n", aValues[i]);
          printf("%lf\n", bValues[i]);
          printf("%lf\n", minTemp[i]);
          printf("%lf\n", maxTemp[i]);
          
          i++;
}}

int main() {
    char metals[numMetal][METALSTR];
    double aValue[numMetal];
    double bValue[numMetal];
    double minTemp[numMetal];
    double maxTemp[numMetal];
    int number = 0;

getDatabase(metals, aValue, bValue, minTemp, maxTemp, &number);
}

The code compiles but when I run the program it stops responding once it enters the while loop

Recommended Answers

All 10 Replies

The code compiles

That totally amazes me.

but when I run the program it stops responding once it enters the while loop

So there's a strong possibility that the problem lies on your while loop statement.

while (fgetc(inFile) != EOF) != NULL) {

'fgetc' returns EOF when read error occurs or the EOF is reached.So this is enough

while(fgetc(inFile)!=EOF)

But wait a minute, the file pointer you declared has a name 'inputFile'.Also that you're using fgetc just to detect the EOF seems a bad idea to me.Instead just read the whole line at a time and extract the information you need one by one.

Why are you reading the first letter of the metal in the while statement? Do you really want the strings to be
luminum
ast-iron
ngot-iron
alleable-iron
ngot-steel
opper
ickel ?

Compare the file handle in these two statements: while (fgetc(inFile) != EOF) != NULL) fscanf(inputFile, "%s", &metalName); I'll bet the program never enters the loop, rather than gets stuck in it.

Member Avatar for jtbens01

The errors you described above were just typos. The original while loop was deleted but it was basically the same thing. Here is an edit that still doesn't work. My problem lies in that I don't know how to get strings and doubles from a text file and I can't find any resources that work for me or that I understand. My original code did compile and opened the file properly but when it entered the loop the program would respond.

while (fgetc(inputFile) != EOF)) {
 
 
          fscanf(inputFile, "%s", &metalName[i]);
          fscanf(inputFile, "%lf", aValues[i]);
          fscanf(inputFile, "%lf", bValues[i]);
          fscanf(inputFile, "%lf", minTemp[i]);
          fscanf(inputFile, "%lf", maxTemp[i]);
 
          printf("%s\n", metalName[i]);
          printf("%lf\n", aValues[i]);
          printf("%lf\n", bValues[i]);
          printf("%lf\n", minTemp[i]);
          printf("%lf\n", maxTemp[i]);
 
          i++;
}

I'm not sure what you mean about not reading in the first letter. Thanks for any support.

Some food for thought:

/*
7
aluminum .012580 .003000 32. 1130.
cast-iron .005441 .001747 32. 1160.
ingot-iron .006375 .001636 32. 1380.
malleable-iron .006503 .001622 32. 930.
ingot-steel .006212 .001623 32. 1380.
copper .009278 .001244 32. 1160.
nickel .007652 .001023 32. 1830.
*/

#include <stdio.h>

int main(void) {
   FILE *fp;
   int i, rowNum;
   char buff[100];
   char name[50][30];   //use malloc or a linked list, to get just what you need, later on
   char dat0[50][30];   //use a struct to unite name and data, later on
   char dat1[50][30];   //so you have one array of structs.
   char dat2[50][30];
   char dat3[50][30];

   if((fp=fopen("metalData.txt", "r")) ==NULL) {
      printf("Error: metalData file did not open!\n");
      return 1;
   }
   
   fscanf(fp, "%d",&rowNum); printf("rows:%d\n", rowNum);
   fgetc(fp); //most necessary, removes the newline char fgets won't do that for you
   
   for(i=0;i<rowNum;i++) {
      printf("\n");
      //get and print the first line of data
      fgets(buff, sizeof(buff), fp); printf("%s", buff); //get one row in the file
      //pull the data into separate arrays, and print them
      sscanf(buff, "%s %s %s %s %s", name[i],dat0[i],dat1[i],dat2[i],dat3[i]); printf("%s %s %s %s %s\n",name[i],dat0[i],dat1[i],dat2[i],dat3[i]); getchar();
   }
   printf("\nEeach row of metal data should be printed twice, and have the same content\n");
   fclose(fp);    
   printf("\n");
   return 0;
}

The errors you described above were just typos. The original while loop was deleted but it was basically the same thing.

You've now seen that posting code that has typos because you didn't bother to check them wastes your time and ours.

My problem lies in that I don't know how to get strings and doubles from a text file

Yes you do. Your code does that.

My original code did compile and opened the file properly but when it entered the loop the program would respond.

Respond with what? If you don't give us the details to make us understand, you're going to waste even more time with us giving half answers and confusing help.

I'm not sure what you mean about not reading in the first letter. Thanks for any support.

What does fgetc(inputFile) do?

Member Avatar for jtbens01

Some food for thought:

/*

   
   fscanf(fp, "%d",&rowNum); printf("rows:%d\n", rowNum);
   fgetc(fp); //most necessary, removes the newline char fgets won't do that for you
   
   for(i=0;i<rowNum;i++) {
      printf("\n");
      //get and print the first line of data
      fgets(buff, sizeof(buff), fp); printf("%s", buff); //get one row in the file
      //pull the data into separate arrays, and print them
      sscanf(buff, "%s %s %s %s %s", name[i],dat0[i],dat1[i],dat2[i],dat3[i]); printf("%s %s %s %s %s\n",name[i],dat0[i],dat1[i],dat2[i],dat3[i]); getchar();
   }
   printf("\nEeach row of metal data should be printed twice, and have the same content\n");
   fclose(fp);    
   printf("\n");
   return 0;
}

Will this work if I use sscanf and first pull out a string and then read the rest of the data in to arrays of doubles instead of char arrays?

ex:

sscanf(buff, "%s %lf %lf %lf %lf", name[i],dat0[i],dat1[i],dat2[i],dat3[i]); printf("%s %lf %lf %lf %lf\n",name[i],dat0[i],dat1[i],dat2[i],dat3[i]); getchar();

Sorry, I didn't realize your floats were being read into character arrays. Of course they should be read into floating point values, not characters! Doh!

Why not change the sscanf() format to %lf for the doubles you want (leave the %s for the name alone of course), and then change char dat0[][] to double data0, and see!

Extremely high probability of success (as in I've already tested it to be sure, but I didn't want to give you the ENTIRE answer).

I'm feeling a lessening of sweat equity on this program, from the OP.

Member Avatar for jtbens01

Why not change the sscanf() format to %lf for the doubles you want (leave the %s for the name alone of course), and then change char dat0[][] to double data0, and see!

Extremely high probability of success (as in I've already tested it to be sure, but I didn't want to give you the ENTIRE answer).

I'm feeling a lessening of sweat equity on this program, from the OP.

That's what I was planning on doing. I tried a variation of that solution and it didn't work. It must have been some other issue. Now that I am home I'll give it a try and let you all know how it goes. Thanks for all the help.

Member Avatar for jtbens01

Okay guys, here we go. This is finally working. Thanks a lot to everyone that was willing to spend some time on this. Here is the final result.

void getDatabase(char metals[][100], double aValue[], 
     double bValue[], double minTemp[], double maxTemp[],
     int *number) {
         
         char fileName[METALSTR]; // Assume the file name is 29 characters or less
         char metalName[100];
         int i;
         
         printf("Enter metals database file name: ");
         scanf("%s", &fileName);
         
         FILE *inputFile = fopen(fileName, "r");
         
         if (inputFile == NULL) {
                       
                       printf("\nThe file specified is not valid.");
                       printf("\nThe program will now terminate.");
                       exit(0);
                       }
                       
         // Get the first number from the file which inidicates number of metals
         fscanf(inputFile, "%d", &number);
         printf("%d", number);
         fgetc(inputFile);
         
         // Loop through to the end of the file and store data in arrays

         for (i = 0; i < 7; i++) {

               printf("\n");
               
               fgets(metalName, sizeof(metalName), inputFile);
               sscanf(metalName, "%s %lf %lf %lf %lf", &metals[i], &aValue[i], 
                                 &bValue[i], &minTemp[i], &maxTemp[i]);
               printf("%s %lf %lf %lf %lf\n", metals[i], aValue[i], bValue[i],
                                          minTemp[i], maxTemp[i]);
                                          
               //getchar();
               }
          
         printf("\n\nThere are %d lines in the file.", i);
         // Close the file
         fclose(inputFile);
         }
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.