简体   繁体   中英

Reading in matrix from text file and displaying

I am having an issue trying to read in a text file that has an array in it. When it runs, the console displays that is is"Reading 1 numbers from file Numbers.txt" and "Showing 1 numbers from data array" with the number 2 on the next line, when there is a 5x5 matrix in the .txt. Any advice of how to fix this would be greatly appreciated.

Here is the text file containing the array.

Numbers.txt:

1 2 3 4 5
5 4 3 2 1
1 2 3 4 5
5 4 3 2 1
1 2 3 4 5

Here is the c code:

#include <stdio.h>

/* Routines called. */
int readNums(char *filename, int *data);
void showData(int *data, int len);

void main(void)
{
    char key;
    int len, data[1000];

    printf("Hello TV Land! \n");

    len = readNums("Numbers.txt", data);

    showData(data, len);

    scanf("%c", &key);
}

int readNums(char *filename, int *data)
{
    FILE *in;
    int len;
    int j;

    in = fopen("Numbers.txt", "r");

    if (in == NULL) {
        printf("Could not find file: %s \n", filename);
    }
    else {
        printf("Reading numbers...\n");

        fscanf(in, "%d", &len);

        printf("reading %d numbers from file %s ....\n", len, filename);

        for(j=0;j<len;j++) {
            fscanf(in, "%d", data + j);
        }

        fclose(in);
    }

    return len;
}


void showData(int *data, int len)
{
    int j;

    printf("Showing %d numbers from data array....\n", len);
    for(j=0;j<len;j++) {
        printf("%d ", *(data + j));
    }
    printf("\n");
}

The first number you scan is the number of items on each line, but in the file the first line is a 1 and not 5 so it reads only one extra number.

The file should probably look like this:

25
1 2 3 4 5
5 4 3 2 1
1 2 3 4 5
5 4 3 2 1
1 2 3 4 5

Or if it's fixed sizes, why read the number or items from the file at all?

You can rely on the C++ Standard Library to write more succinct code. Granted—it is not easy to learn the whole thing in one sitting (it takes practice, which is one of the reasons why I reply to questions such as this one, to practice myself).

The following code does what you ask for, namely: read from a file and print the contents to the screen. It could be made much more flexible (eg, provide filename via command line argument); it should be extended to handle exceptions, close the file (in this case it is done automatically when the program exits), etc. On the other hand, look at how succinct (if not obvious) the code is.

If you want to learn what each construct is supposed to do, please go to cppreference.com, it has helped me a lot.

// These statements "bring into the program" the "hooks" needed to
// invoque the functionality available in the Standard Library. In C++
// you "only pay for what you use", that is why you should only
// "include" what you need.

// header name        it providest the means to ...
#include<iterator> // "walk through" a thing
#include<iostream> // handle input (i) / output (o) streams
#include<fstream>  // handle file streams
#include<vector>   // handle collections of items

// core entry point to the program
int main() {
  // all data will be read into a collection of integers (in this
  // case, you could have created a collection of any type). Vectors
  // can grow and shrink automatically, and can be traversed
  // (iterated; walked-through) efficiently. There are other
  // "collections" available (list, array, set, queue, stack, etc)
  // each with different capabilities

  std::vector<int> data;

  // create an "input stream" feed from a file called "numbers.txt"
  std::ifstream fp("numbers.txt");

  // copy the contents of the "input stream" to the vector. An
  // "istream_iterator" is simply an "agent" which can "walk through"
  // any "input stream". In this case, "walk through" means "give me
  // integers until there are none". A "back inserter" is an "agent"
  // which can "push back" stuff into a container. In this case it
  // will "push back" integers into a vector; the vector being "data",
  // our container defined above.
  std::copy(std::istream_iterator<int>(fp), // this denotes "start of stream"
            std::istream_iterator<int>(),   // this denodes "end of stream"
            std::back_inserter<std::vector<int>>(data)); // this is
                                                         // where I
                                                         // want to
                                                         // store the
                                                         // copied
                                                         // value

  // now that I have copied all the values of the file into the data
  // vector, I want to copy them again, this time to the screen output
  // (called "cout"). An "ostream iterator" can "walk through"
  // anything that is an "output stream".
  std::copy(data.begin(), // denotes "start of data"
            data.end(),   // denotes "end of data"
            std::ostream_iterator<int>(std::cout, " "));

  // finally --- notice that we do not need the vector at all! We
  // could have copied the input stream directly into the output
  // stream! The statement would be as follows:

  fp.seekg(0); // this tells the "stream" to "go back to the
               // beginning". We need to do this because I already
               // "walked through it", and it is currently at the end.

  std::copy(std::istream_iterator<int>(fp), // this denotes "start of stream"
            std::istream_iterator<int>(),   // this denodes "end of stream"
            std::ostream_iterator<int>(std::cout, " "));

  return 0;
}

Compile instruction (I use gcc 4.8.1): g++ example.cpp -std=c++11

Output: 1 2 3 4 5 5 4 3 2 1 1 2 3 4 5 5 4 3 2 1 1 2 3 4 5

Now, how about we do without vectors?

#include<iterator>
#include<iostream>
#include<fstream> 

int main() {

  // We can copy the input stream directly into the output stream!  

  std::ifstream fp("numbers.txt");

  std::copy(std::istream_iterator<int>(fp), 
            std::istream_iterator<int>(),
            std::ostream_iterator<int>(std::cout, " "));

  return 0;
}

Output: 1 2 3 4 5 5 4 3 2 1 1 2 3 4 5 5 4 3 2 1 1 2 3 4 5

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