【问题标题】:Read a text file and store into two different arrays: a string array and float array读取文本文件并存储到两个不同的数组中:字符串数组和浮点数组
【发布时间】:2017-03-12 19:04:52
【问题描述】:

我无法将我的代码存储到两个不同的数组中。以下文本文件包含如下格式:name,1,2,3,4,5anothername,6,7,8,9,10...

例如它可能是这样的,我将它命名为 test.txt:

Drake,1,2,3,4,5
Kanye West,6,7,8,9,10
Ka,11,12,13,14,15,16
Young Thug,17,18,19,20
Kendrick Lamar,21,22,23,24,25

到目前为止,这是我的代码:

#include <iostream>
#include <fstream>
#include <stdlib.h>
using namespace std;

int main(){
    ifstream inputFile;
    inputFile.open("test.txt");

    if (inputFile.fail()){
        cout << "File open error!" << endl;
        return -1;
    }

    string namesarray[25];    //array used to store names
    float numbersarray[25];    //array used to store numbers
    string line;    //string used to read text file
    int i = 0;    //counter for entire text input
    int j = 0;    //counter for namesarray
    int k = 0;    //counter for numbersarray

    while(getline(inputFile, line, ',')){
        if (line[i] >= 'A' && line[i] <= 'Z'){
            namesarray[j] = line;
            j++;
        }
        else{
            numbersarray[k] = stof(line);
            k++;     
        }
        i++;
    }
    inputFile.close();
}

我的问题是我无法将所有名称存储到字符串数组中,但数字存储到浮点数组中就好了。我的代码只存储在名字中,然后是一个随机数。例如,如果我创建一个循环来检查名称或数字是否正确存储

for (int a = 0; a < 25; a++){
    cout << numbersarray[a] << endl;
}

数字存储得很好,但检查名称时它不会将所有名称都存储在那里。如果我正在检查该行的第一个字母,如果它包含一个字母,它不应该将名称存储在那里吗?我不想使用 isalpha() ,因为它仍然输出相同的问题。

for (int a = 0; a < 25; a++){
    cout << namesarray[a] << endl;
}

【问题讨论】:

  • "string namesarray[25];"? ...您为什么不使用std::vector&lt;std::string&gt; ?...另请阅读why using eof() as loop condition is considered wrong
  • 我还没有学过向量,但我仍然坚持使用数组。我已经设置了一个与上面类似的 while 循环,例如:while(getline(inputFile, line, ',')) 但我仍然遇到同样的问题。
  • 据我所知,i 在这段代码中几乎一文不值。无论如何,如果您真的想将其作为逐行验证并输入中间的std::stringstd::istringstream 可能会使代码更容易理解。并且认真;一个结构向量,每个都包含一个名称和一个分数向量是正确的方法。
  • 我将如何使用 istringstream?

标签: c++ arrays file-io


【解决方案1】:

对于getline(),第三个参数不会删除逗号。它指定函数填充字符串的分隔符。因此,根据您的输入文件,它将获取名称。

【讨论】:

  • 修复了那部分
  • 不错。那么这个问题就无关紧要了。您现在应该搜索 stackexchange 以了解如何按分隔符拆分字符串。有几种解决方案。
【解决方案2】:

我找不到i++;的用法。你总是需要寻找line[0]

我建议使用isdigit(line[0]) 来检查它是数字还是字符

您的代码的问题是您只检查大写字母。 大写字母仅存在于带有名称的字符串的第一个字符中。 所以当i++;变成i&gt;0时,line[i]就不再是大写了,变成了小写。

另外我想让你知道stof 只适用于 c++11

【讨论】:

    【解决方案3】:

    getLine 函数的分隔符是一个逗号,因此当它到达每个名称的最后一个数字时,它会读取一个字符串中的数字和名称。要修复它,请考虑以下内容:

    bool letter = true;
    bool letterNum = false;
    int index = 0;
    if((line[0] >= '9' && line[0] >= '0') || line[0] == '.') {
        letter = false;
    }
    for(int l = 0; l < line.length()) {
        if((letter && ((line[l] >= '9' && line[l] >= '0') || line[l] == '.')) || (!letter && !((line[l] >= '9' && line[l] >= '0') || line[l] == '.'))) {
            index = l;
            l = line.length();
        }
    }
    
    if(letter && index == 0) {
        namesarray[j] = line;
        j++;
        i++;
    }
    
    if(!letter && index == 0) {
        numbersarray[k] = atoi(line);
        k++;
        i++;
    }
    
    if(letter && index != 0) {
        namesarray[j] = line.substr(0, index);
        numbersarray[k] = stof(line.substr(index, line.length() - index));
        j++;
        k++;
        i += 2;
    }
    
    if(!letter && index != 0) {
        numbersarray[k] = stof(line.substr(0, index));
        namesarray[j] = line.substr(index, line.length() - index);
        j++;
        k++;
        i += 2;
    }
    

    代替:

    if (line[i] >= 'A' && line[i] <= 'Z'){
        namesarray[j] = line;
        j++;
    }
    else{
        numbersarray[k] = stof(line);
        k++;     
    }
    i++;
    

    在while循环中。您也可以使用ifstream &gt;&gt; string,因为它一次读取一行,您可以只解析逗号之间的每个子字符串。这可能看起来像:

    #include <iostream>
    #include <fstream>
    #include <stdlib.h>
    using namespace std;
    
    int main(){
        ifstream inputFile;
        inputFile.open("test.txt");
    
        if (inputFile.fail()){
            cout << "File open error!" << endl;
            return -1;
        }
    
        string namesarray[25];    //array used to store names
        float numbersarray[25];    //array used to store numbers
        string line;    //string used to read text file
        int i = 0;    //counter for entire text input
        int j = 0;    //counter for namesarray
        int k = 0;    //counter for numbersarray
    
        while(!inputFile.eof()){
            string data;
            inputFile >> data;
            int lastIndex = 0;
            for(int l = 0; l < data.length(); l++) {
                if(data[l] == ',' || l == data.length() - 1) {
                    line = data.substr(lastIndex, l - lastIndex);
                    lastIndex = l + 1;
                    if (((line[l] >= '9' && line[l] >= '0') || line[l] == '.')){
                        numbersarray[k] = stof(line);
                        k++;    
                    }
                    else{
                        namesarray[j] = line;
                        j++;
                    }
                    i++;
                }
            }
        }
        inputFile.close();
    }
    

    但是,这仅在每个名称及其数字由 \n 分隔时才有效。如果是,这是更好的选择。但如果不是,请使用第一种方法。

    【讨论】:

      【解决方案4】:

      最好使用std::getline() 读取整行,然后std::istringstream 解析每一行,例如:

      #include <iostream>
      #include <string>
      #include <fstream>
      #include <sstream>
      
      using namespace std;
      
      int main()
      {
          ifstream inputFile;
          inputFile.open("test.txt");
          if (!inputFile)
          {
              cout << "File open error!" << endl;
              return -1;
          }
      
          string namesarray[25]; //array used to store names
          float numbersarray[25*5]; //array used to store numbers
          string s; //string used to read text file
          int i = 0; //counter for entire text input
          int j = 0; //counter for namesarray
          int k = 0; //counter for numbersarray
      
          while (getline(inputFile, s))
          {
              istringstream iss(s);
              getline(iss, namesarray[j], ',');
              ++j;
      
              while (getline(iss, s, ','))
              {
                  numbersarray[k] = stof(s);
                  ++k;
              }
      
              ++i;
          }
      
          inputFile.close();
          return 0;
      }
      

      【讨论】:

        【解决方案5】:

        为什么在 else 语句中是 i++?您必须检查 i 变量数组的第一个元素,而不是添加它。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-05-28
          • 1970-01-01
          • 1970-01-01
          • 2012-08-18
          相关资源
          最近更新 更多