从文本文件中读取矩阵并显示

时间:2013-09-12 16:45:43

标签: c++ c arrays matrix

我在尝试读取包含数组的文本文件时遇到问题。当它运行时,控制台显示的是“读取文件Numbers.txt中的1个数字”和“显示数据数组中的1个数字”,下一行中的数字为2,当.txt中有5x5矩阵时。如何解决这个问题的任何建议将不胜感激。

这是包含数组的文本文件。

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

这是c代码:

#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");
}

2 个答案:

答案 0 :(得分:2)

您扫描的第一个数字是每行的项目数,但在文件中第一行是1而不是5,所以它只读取一个额外的数字。

文件应该如下所示:

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

或者,如果它是固定大小,为什么要读取文件中的数字或项目?

答案 1 :(得分:1)

您可以依靠C ++标准库来编写更简洁的代码。当然 - 一次性学习整个过程并不容易(这需要练习,这是我回答这个问题的原因之一,就是练习自己)。

以下代码执行您的要求,即:从文件中读取并将内容打印到屏幕上。它可以更加灵活(例如,通过命令行参数提供文件名);它应该被扩展为处理异常,关闭文件(在这种情况下,它是在程序退出时自动完成的),等等。另一方面,看看代码是如何简洁(如果不是很明显)。

如果你想了解每个构造应该做什么,请访问cppreference.com,它对我帮助很大。

// 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;
}

编译指令(我使用gcc 4.8.1):g++ example.cpp -std=c++11

输出: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

现在,没有载体我们怎么办?

#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;
}

输出: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