包含字符串和整数的文件输入

时间:2014-12-24 08:03:13

标签: c++ arrays file file-io

我有一个文件,其内容如下:

Aadam
50
Aadam
0
Aad
0123
Waleed
12345

现在,我需要将第一行存储在字符串数组中,将第二行存储为整数数组。 这是我写的源代码....

ifstream infile ("File.txt");
string name [20];
int score [20};
for (int i = 0; !infile.eof(); i++)
            {
                getline(infile, name[i]);
                infile >> scores[i];
            }

好吧,该程序成功读取第一行,但之后它什么也没做。 我首先尝试了另一种方法,其中我首先将整数存储为临时字符串,然后使用“stoi”将该字符串转换为整数,这就像魅力一样。像这样:

for (int i = 0; !infile.eof(); i++)
            {
                getline(infile, name[i]);
                string temp;
                getline(infile, temp);
                scores[i] = stoi(temp);
            }

但问题是我不能使用stoi。它在我的计算机上工作正常,但我必须向可能没有支持C ++ 11的编译器的老师提供源代码。这对我来说可能是一个问题。 所以我需要另一种方法来从文件中输入数据。 所以,如果你知道这样做的方法,请告诉我。

4 个答案:

答案 0 :(得分:1)

而不是“stoi”而不是“atoi”:

scores[i] = atoi(temp.c_str());

http://en.cppreference.com/w/cpp/string/byte/atoi

它在C ++ 11之前一直存在。

答案 1 :(得分:1)

如果你不能使用stoi,你可以使用字符串流。

std::ifstream infile ("File.txt");
std::string name[20];
int score[20];
for (int i = 0; !infile.eof(); i++){
    getline(infile,name[i]);
    std::string temp;
    getline(infile,temp);

    std::stringstream s; 
    s << temp; 
    int integertemp; 
    s >> integertemp; // This will convert string to integer, just like how it is with iostreams.
    score[i] = integertemp;
}

答案 2 :(得分:0)

使用getline后问题出在>>

要解决此问题,您可以添加以下方法:

istream& eatwhites(istream& stream)
{
    // to define white spaces manually:
    //const string skip=" \t\r\n";
    //while(string::npos != skip.find(stream.peek())){
    //   stream.ignore();
    //}

    //or just use isspace:
    while(isspace(stream.peek())){
        stream.ignore();
    }

    return stream;
}

并按照以下方式编写每个getline

string name;
getline( eatwhites(infile), name); 

以及cin

string name;
getline( eatwhites(cin), name); 

答案 3 :(得分:0)

问题的要点是,如果输入包含:

Aadam\n
50\n

你做了:

  getline(infile, name[i]);    // name[i] contains "Hello", \n consumed
  infile >> scores[i];         // scores[i] contains 50

然后输入仍然包含:

\n

50之后。 >> int运算符在其提取的数字后不会使用任何尾随换行符或其他字符。

然后,对于循环的下一次,输入流包含:

\n
Aadam\n
0\n

你做了:

  getline(infile, name[i]);    // name[i] contains "", \n consumed
  infile >> scores[i];         // input failure

由于Aadam(第二个)无法解析为int>>运算符会将infile置于失败状态。您的代码永远不会清除故障状态也不会检查它,因此所有后续操作都会失败,并且您的代码会进入无限循环。

其他问题是using eof() is a bad idea和(如果读数已修复)如果文件中有超过20对项目,则会出现缓冲区溢出。


要解决I / O问题,您可以这样写:

for (int i = 0; i < 20; ++i)
{
    getline(infile , name[i]);
    infile >> scores[i];
    infile.ignore(SIZE_MAX, '\n');

    if ( !infile )
        break;
}

这里的ignore行意味着在读取数字后,它将消耗该行的剩余部分。

当循环结束时,i将包含成功读取的对数。如果输入失败,break离开循环的条件很重要。