我在尝试读取包含数组的文本文件时遇到问题。当它运行时,控制台显示的是“读取文件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");
}
答案 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