hi, wonder if anyone can help me.

I have a text file with the following format:

town_name followed by 12 real numbers i.e

London 7.24 8.15 6.45 3.24 3.66 2.45 4.71 6.78 6.45 8.61 7.45 6.55
Manchester 12.23 10.67 7.56 4.34 5.55 6.29 8.77 14.77 9.77 7.49 8.34 7.66
Liverpool 10.12 6.76 7.87 6.66 4.56 7.82 12.63 9.62 6.02 7.94 8.34 9.18
Bristol 6.55 8.61 4.67 4.86 5.55 2.39 6.66 4.91 2.93 4.66 4.81 7.39
ZZZZZ

the ZZZZZ is a sentinel value which tells my program to stop reading from the file. I need to read the data file and display it in the console window. However I can only get it to work when I have only one number next to the town name, as soon as the others go in, i get strange results. the entire data set needs to be held in an array as I need to do calculations to the data, below is the code I have developed so far...

#include <stdio.h>
#include <string.h>

const int maxrows=12;
const int maxcols=12;
const int maxchar=10;

static char place[maxrows][maxchar];
static char dummy[maxchar];
float rain[maxrows];
float average, annual, wet, dry; 

FILE *fp;

main ()
{
    int i=0;
    if ((fp = fopen("data1.txt", "r"))==NULL)
       printf("Error opening file\n");
    else
    {
        do
        {
            printf("\n");
            fscanf(fp,"%s",&dummy);
            if (strcmp(dummy, "ZZZZZ") !=0)
            {
                strcpy(place[i],dummy);
                fscanf(fp,"%f",&rain[i]);
                printf("%10s\t%2.2f", place[i],rain[i]);
                i++;
            }
        } while ((strcmp(dummy,"ZZZZZ") !=0) and (i<maxrows));
    }
    fclose(fp);
    getchar();
}

thanks in advance

Think in terms of rows of records consisting of fields instead of rows and columns:

in = fopen ( "data1.txt", "r" );
if ( in == NULL ) {
  /* Error */
} else {
  int i, j;

  do {
    fscanf ( in, "%s", dummy );
    if ( strcmp ( dummy, "ZZZZZ" ) == 0 )
      break;

    /* Fill the ith record */
    strcpy ( place[i], dummy );
    for ( j = 0; j < max_cols; j++ )
      fscanf ( in, "%f", &rain[i] );

    /* Display the ith record */
    printf ( "%10s\t", place[i] );
    for ( j = 0; j < max_cols; j++ )
      printf ( "%2.2f", rain[i] );
    printf ( "\n" );
  } while ( i < max_rows );
}

First thing I saw was you mixed a little basic with C.

while ((strcmp(dummy,"ZZZZZ") !=0) [b][u]&&[/u][/b] (i<maxrows));

not and. Other than that you were so close. All you needed to do was make another loop inside your do loop

strcpy(place[i],dummy);
 
	for (int x = 0; x < 12; x++) {
		fscanf(fp,"%f",&rain[x]);
		printf("[b]\n\t[/b]%10s\t%2.2f", place[i],rain[x]); }
	i++;

and that solved the problem. I also cleaned up the display a little with the carriage return / tab.

Didn't mean to discredit your response Narue, but it didn't show up until I hit submit.

thanks for your response guys,

I had actually just about figured it out before I read the resonses but they were really helpful, just pushed me in the right direction!

thanks again guys

>First thing I saw was you mixed a little basic with C.
You're gonna love this. :) In C, since the 95 ammendment, the header <iso646.h> defines macros such as and, or, and not_eq as a reasonable alternative to the nasty trigraphs for implementations that don't support the requisite characters to represent the base language. In standard C++ all of those macros are language keywords. So it's not quite a stretch to imagine C or C++ code using them. ;)

can someone have a look at this for me please? i cannot understand why i am getting all the spare 0.00 numbers when i compile!

a text file is required as before, the details are in my first post in this thread

thanks

#include <stdio.h>
#include <string.h>

const int maxrows=12;
const int maxcols=12;
const int maxchar=10;

static char place[maxrows][maxchar];
static char dummy[maxchar];
float rain[maxrows][maxcols];
float average, annual, wet, dry; 

FILE *fp;

main ()
{
    int x=0;
    if ((fp = fopen("data1.txt", "r"))==NULL)
       printf("Error opening file\n");
    else
    {
        do
        {
            printf("\n\n");
            fscanf(fp,"%s",&dummy);
            if (strcmp(dummy, "ZZZZZ") !=0)
            {
                strcpy(place[x],dummy);
                printf("%10s", place[x]);
                annual=0;
                for (int i=0; i<maxrows; i++) 
                {
                    for(int j=0; j<maxcols; j++)
                    {
                        fscanf(fp,"%f",&rain[i][j]);
	                    printf("\t%2.2f",rain[i][j]); 
	                    annual=annual+rain[i][j];
                    }    
	             }printf("\tAnnual rainfall is %3.2f", annual);
	             x++;
            }
        } while ((strcmp(dummy,"ZZZZZ") !=0) && (x<maxrows));
    }
    fclose(fp);
    getchar();
}

never mind, its sussed now, was a simple error on my part!!

Your nested for loops mean that you are trying to read 144 values each line. To me it looks like the do...while is attempting to be what the first for loop should be: rows. I'd do something more like this.

for ( int i = 0; i < maxrows; ++i )
      {
         fscanf ( fp,"%s", place[i] );
         if ( strcmp ( place[i], "ZZZZZ" ) == 0 )
         {
            break;
         }
         printf ( "%10s", place[i] );

         annual = 0;
         for ( int j = 0; j < maxcols; ++j )
         {
            fscanf ( fp, "%f", &rain[i][j] );
            printf ( "\t%2.2f", rain[i][j] );
            annual = annual + rain[i][j];
         }
         printf("\tAnnual rainfall is %3.2f\n", annual);
      }

Unless the format of your file has changed, you're trying to read too many floats, and fscanf is failing miserably when you get to the next city. Here's how any logic you use should work:

for each line
  read the name
  read 12 floats

Anything else will give you incorrect output. As it is, your code is trying to do this:

for each line
  read the name
  read 144 floats

Notice the difference?

yes, i figured it out now, i realised that it was trying to read in far too many values but it is working fine now..

thanks again

This article has been dead for over six months. Start a new discussion instead.