简体   繁体   English

在C ++中从文件读取整数和字符

[英]Reading integers and chars from a file in C++

So, i'm trying to write a program that can read data from a file. 因此,我正在尝试编写一个可以从文件读取数据的程序。 The file consists of integers, chars and doubles. 该文件由整数,字符和双精度数组成。 And i have to be able to assign them to different variables for further calculation (this is actually just a part of a bigger program). 而且我必须能够将它们分配给不同的变量以进行进一步的计算(这实际上只是更大程序的一部分)。 I've searched around the web (here also), and i've seen different solutions. 我已经在网上搜索了(这里也是),并且看到了不同的解决方案。 stringstream, vectors and whatnot. 串流,向量和诸如此类。 The one i got furthest with, was using "skipws" when reading. 我最喜欢的那个是在阅读时使用“ skipws”。 But i can't seem to read the integers properly. 但是我似乎无法正确读取整数。

I would prefer a solution that requires the use of as few methods (streams, gets etc) as possible. 我希望有一种解决方案,要求使用尽可能少的方法(流,获取等)。 But if i need more, i can live with it. 但是,如果我需要更多,我可以忍受。

#include <iostream>
#include <fstream>
#include <cstring>

using namespace::std;

int main()
{
    int j = 0, kill = 0, i;
    char initials[10];
    int results[10];
    double avg;

    ifstream read("P1.txt");

    if (!read) //test to see if file can be opened.
    {
        cerr << "Error" << endl;
        exit(1);
    }

    while(kill != 1) //kill = 1 same as eof. Just my weird way of coding. 
    {
        switch (j)
        {
            case 0:     //read the first line of data, which is the chars.
                read >> skipws >> initials;
                j++;
                break;

            case 1: //read the second line of data, which is 10 integers and whitespace
                for (i=0;i<10;i++)
                read >> skipws >> results[i];
                j++;
                break;

            case 2:     //read the last line which is a single double.
                read >> skipws >> avg;
                j++;
                break;

            case 3: //check for end of file. 
                if(read.eof() == 0)
                    kill = 1;
                break;
        }
    }
    //the 3 lines below are just writing the contents of the file to the prompt. 
    //It's to check that values are stored correctly for further use. 
    cout << initials << endl; 
    cout << results << endl;
    cout << avg << endl;

    return 0;
}

I know exactly what y input file, "P1.txt", will look like, because i create it myself in another part of the program. 我确切知道y输入文件“ P1.txt”是什么样子,因为我是在程序的另一部分中自己创建的。 It looks like this: 看起来像这样:

ccs
2 4 5 3 1 4 6 1 1 1
2.8       

Those 3 lines gives me the initials of a player, his results of 10 games and his average score. 这3行给了我球员的名字缩写,他10场比赛的结果以及他的平均得分。 In short, the data of one player. 简而言之,一个玩家的数据。 In the final program, i need to be able to read values for maybe 10 players. 在最终程序中,我需要能够读取大约10个玩家的值。

I'm expecting the 3 cout lines in the end to show this: 我期望最后的3条提示行显示如下:

ccs
2453146111
2.8

Now, this is as far as i have gotten. 现在,据我所知。 If i declare results[10] as char i can get this in my console: 如果我将results [10]声明为char,则可以在控制台中获取它:

ccs
2453146111ccs
2.8

If i declare it as int i get this 如果我将其声明为int,我会得到这个

ccs
0x7fff5fbff6c0
2.8

Obviously, i can see that values aren't stored properly and something is out of hand, but i need another persons eyes on this. 显然,我可以看到值存储不正确并且有些东西失控,但是我需要其他人对此进行关注。 I'm out of clues. 我没有头绪。

I know this is a messy way to do it and that it can be done in less space, but i'm new to C++, so this made sense to me, and made it fairly easy for me to locate my mistakes, until now. 我知道这是一种麻烦的方式,可以在较小的空间内完成,但是我对C ++并不陌生,所以这对我来说很有意义,并且直到现在我仍然很容易找出错误。

I tried to explain it as well as i could. 我尽力解释了一下。 This is my first post here, so please tell me if you need more info. 这是我在这里的第一篇文章,所以请告诉我是否需要更多信息。

Thanks in advance!! 提前致谢!! Chris. 克里斯。

when results is int[10] and you make cout << results << endl it will print the array memory address you should make loop that print result[i] in each iteration. 当result为int [10]并且您使cout <<结果<< endl时,它将打印出数组内存地址,您应该在每次迭代中进行循环以打印result [i]。

for(i=0;i<10;i++){
      cout<< result[i]; 
}

and it will give the correct result 它会给出正确的结果

I would suggest the following if you are using C++: 如果您使用的是C ++,我建议以下内容:

  • Create three stringstream s 创建三个stringstream
  • Read each line into one stringstream 将每一行读入一个stringstream
  • For each line use (when your stringstream is called ss ): 对于每一行,(当您的stringstream称为ss ):
    • ss >> c (with c your character) ss >> c (用c您的角色)
    • ss >> i (with i your integer) ss >> i (使用i您的整数)
    • ss >> d (with d your double) ss >> d (带d的双精度字)
  • Put the values in a vector when more than one input can be given on a line. 当一行上可以有多个输入时,请将值放在向量中。

Some code: 一些代码:

    string s[3] = {"ccs",
        "2 4 5 3 1 4 6 1 1 1",
        "2.8"
    };
    stringstream ss[3];

    /*
    Open file, get the first line into s[0], second into s[1] and third into s[2]
    */

    ss[0] << s[0];
    ss[1] << s[1];
    ss[2] << s[2];
    char c;
    int i;
    double d;

    vector<char> initials;
    vector<int> scores;
    vector<double> averages;

    while (ss[0] >> c) {
        cout << c << " ";
        initials.push_back(c);
    }
    cout << endl;
    while (ss[1] >> i) {
        cout << i << " ";
        scores.push_back(i);
    }
    cout << endl;
    while (ss[2] >> d) {
        cout << d << " ";
        averages.push_back(d);
    }
    cout << endl;

This problem is made significantly easier by the fact that your data takes a known format. 由于您的数据采用已知格式,因此使此问题变得更加容易 Don't let this go to waste. 不要浪费它。

string initials;
vector<int> r(NUM_SCORES);
double avg;

Now to get the data: 现在获取数据:

ifstream infile;
infile.open(...);
while(infile >> initials){ // i.e. "while there's another player"
    for(int i=0; i<r.size(); i++) infile >> r.at(i);
    infile >> avg;
}

Job done. 任务完成。

cout << "Player " << intials << " scored:" << endl;
for(int i=0; i<r.size(); i++) cout << r.at(i);
cout << endl << "giving him an average of " << avg << endl;

Also when you read in a value from a file, it is not an "int" data type. 同样,当您从文件中读取值时,它也不是“ int”数据类型。 you cannot just push it back to a array of int's and expect it to work, you will probably need to convert it to an int using something like std::stoi 您不能只将其推回int数组并期望它能工作,您可能需要使用std::stoi东西将其转换为int

Don't re-invent the wheel, you can use Boost::tokenizer to tokenize the string and use Lexical_cast to convert strings to numbers. 不要重新发明轮子,可以使用Boost :: tokenizer标记字符串,并使用Lexical_cast将字符串转换为数字。

If you want to use plain c you can use strtok for tokenizing the string 如果要使用纯c,则可以使用strtok对字符串进行标记

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM