0

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

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

数字.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");
}
4

2 回答 2

2

您扫描的第一个数字是每行上的项目数,但在文件中,第一行是 a1而不是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

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

于 2013-09-12T16:51:16.143 回答
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

于 2013-09-12T17:19:51.610 回答