String to String构建函数,为每个字符串使用不同的索引变量

时间:2011-07-11 18:58:55

标签: c++ string parsing

下面有2个程序。在第一个我已经条纹化了除问题循环之外的所有东西,当我这样做时它起作用。在第二个程序中(仍然是我正在处理的程序)我使用相同的逻辑,但是名为for_loop_buffer的子字符串永远不会加载。

基本上我正在解析一个包含cdf文件记录的字符串。 for循环缓冲区是我构建每个字段并将其保存到我的类的地方。我已经在这里旋转了几天,任何帮助都会受到赞赏。

编辑:

以下是该程序正在阅读的文件中的内容: 0,Nicole 0,Debbie -

计划1

/*******************************************************\
* Debug Version 02-b-1 - string to string build         *
*                                                       *
* Saving a Person Object to file                        *
* This program will have a class that can save and      *
* retrieve itself to and from a flat file in cdf format *
*                                                       *
* The program will accept screen input for subsequent   *
* Object store call and will allow a print command that *
* will create a file of mailing labels.                 *
\*******************************************************/
#include <cstdlib>
#include <iostream>
#include <string>

std::string current_person = "Why does this not work?     ";         // CDF String version of person record from file
std::string for_loop_buffer = "                                        ";        // the substring buffer
int counter2 = 0;

int main( )
{
    for (int i = 0;i <= 23;++i){

/*****************************************************************************\
* This next line apears to be the problem                                     *
\*****************************************************************************/
          for_loop_buffer[counter2] = current_person[i];

  std::cout << "DEBUG - Current person " << current_person << std::endl;
  std::cout << "DEBUG - current Person element " << current_person[i] << std::endl;
  std::cout << "DEBUG - for Loop Buffer " << for_loop_buffer << std::endl;
  std::cout << "DEBUG - for Loop Buffer element " << for_loop_buffer[counter2] << std::endl;
  std::cout << "DEBUG - for Loop Buffer counter " << counter2 << std::endl;
      ++counter2;

    }  // close for


return (0);
}

计划2

/*******************************************************\
* Debug Version 02 - Read data from a cdf file          *
*                                                       *
* Saving a Person Object to file                        *
* This program will have a class that can save and      *
* retrieve itself to and from a flat file in cdf format *
*                                                       *
* The program will accept screen input for subsequent   *
* Object store call and will allow a print command that *
* will create a file of mailing labels.                 *
\*******************************************************/

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
/***************************************************************\
* Class Definition - person                                     *
*                                                               *
* Member functions                                              *
* save_person -- Save the person object to a flat file in CDF   *
* get_person -- Retrives a persons data from a CDF flat file    *
\***************************************************************/

// Definition of the Class
class person_class {

  public:
    struct person_contact {
      int person_number; // System assigned not on ui  
      std::string first_name;
    };


  // Declarations for the method Prototypes
  public:            

    // A Function that retrieves 1 person from file and
    // provides it to the user
    void get_person();

} person;


/*********************************************************\
* person_class::get_person -- get a data record from file *
*                                                         *
\*********************************************************/
inline void person_class::get_person()
{
// Declaration of private variables for this method

std::string ui_first_name;     // User Input from Keyboard
person_contact target_person;  // Name of the opbect we are filling
std::string current_person;    // CDF String version of person record from file

  std::cout << "Enter the First Name of the person you are looking for: ";
  std::cin >> ui_first_name;

  std::cout << std::endl << "Matching Records: " << std::endl;
  // Open file
  std::ifstream input_file("ntc_db02test.ntc");

  std::cout << "DEBUG - I opened the file " << std::endl;

  current_person.clear();
  while (input_file.good()){

  std::cout << "DEBUG - I have entered the while loop " << std::endl;


    // Grab the next record from a comma delimited file
    getline(input_file,current_person);

  std::cout << "DEBUG - I have performed a getline " << std::endl;
  std::cout << current_person << std::endl;


    // I need a mechanism to build substrings

    // Substring Buffer stuff
    int buffer_pointer = 0;             // pointer to the next position in the substring buffer
    std::string for_loop_buffer ="                                        ";        // the substring buffer
      for_loop_buffer.clear();

    int field_index = 0;                // Which field is next to load

/*******************************************************************\
* If everything went as planned I have a single CDF person record   *
* in the current_person string and now all I have to do is parse    *
* it and place each field in the current instance.                  *
\*******************************************************************/
    // load the instance with the record data from the file
    for (int i = 0;i < current_person.length();++i){

  std::cout << "DEBUG - I am in the for loop " << std::endl;

      // look for the end of the CDF field
      if(current_person[i] == ','){
        // Write the buffer to the next field
  std::cout << "DEBUG - I found a comma " << std::endl;

        switch (field_index) {

          case 0:
             stringstream(for_loop_buffer) >> target_person.person_number;
  std::cout << "DEBUG - Field Index " << field_index << std::endl;
  std::cout << "DEBUG - For Loop Buffer " << for_loop_buffer << std::endl;
  std::cout << "DEBUG - Person Number " << target_person.person_number << std::endl;
            break;

          case 1:
             stringstream(for_loop_buffer) >> target_person.first_name;
  std::cout << "DEBUG - First Name " << target_person.first_name << std::endl;
            break;


          default:
            std::cout << "This should not happen, index not functioning " << '\n';
            break;
        }  // Close Switch

        // clear the buffer
          for_loop_buffer.clear();  //SE
          buffer_pointer = 0;
        // set up the next field load - increment the field index
        ++field_index;   // 
      }else{  // close if

  std::cout << "DEBUG - not a comma " << std::endl;

        // If the character is not a comma
        // add the character to the buffer

/*****************************************************************************\
* !!!!!!!!!!!!   This next line apears to be the problem  !!!!!!!!!!!!!!!     *
\*****************************************************************************/
          for_loop_buffer[buffer_pointer] = current_person[i];

  std::cout << "DEBUG - Primary Index i " << i << std::endl;
  std::cout << "DEBUG - current Person element " << current_person[i] << std::endl;
  std::cout << "DEBUG - Buffer Pointer " << buffer_pointer << std::endl;
  std::cout << "DEBUG - for Loop Buffer element " << for_loop_buffer[buffer_pointer] << std::endl;
  std::cout << "DEBUG - for Loop Buffer " << for_loop_buffer << std::endl;


        // Increment the buffer pointer
          ++buffer_pointer;
      } // close else
    }  // close for
    if (target_person.first_name == ui_first_name){

      // Code to print out full record

      std::cout << target_person.first_name << " "
                << std::endl;
    }  // Close if
  }  // Close While
  input_file.close();

}  // Close Class


/******************************************************************************\
* The idea this time is to do as little in the main as possible and as much    *
* in the class as is appropriate. So rather than read in data and pass it to   *
* the method, I will call the method and let it do its own UI reading.         *
\******************************************************************************/


int main( )
{

/**********************************************************\
* Ask the user if they want to Create a new person record  *
* n or find a record in the database f                     *
\**********************************************************/

  // Set up for user input
  char command = 'f';

  std::cout << " What do you want to do? New Person (n) or Find Person (f) ";
  std::cin >> command;

  while (command == 'n' || command == 'f'){
    if (command == 'n'){

      std::cout << "Do Nothing" << std::endl;

    } else if (command == 'f'){
      person_class current_person_object;
      current_person_object.get_person();  

    }
  command = 'x';
  std::cout << "I am Back in Main" << std::endl;
  }
std::cout << "You entered something other than a -n- or a -f-, program terminating now" << std::endl;

return (0);
}

2 个答案:

答案 0 :(得分:3)

您正在循环遍历字符串,将其拆分为逗号,但是有标准库函数可以为您简化此操作。这听起来像家庭作业,所以我不会发布任何代码答案,但这里有一些提示:

在循环中使用上述两个函数,您可以用更少的代码选择字段,这样更容易理解。

或者,可以直接从流中读取值,因为您使用的std::getline函数有一个额外的参数来指定哪个字符终止该行(即逗号)。

答案 1 :(得分:2)

难以看清代码,但在您的“真实”代码中,您说for_loop_buffer.clear();,这是for_loop_buffer = "";的同义词,后来我认为您正在访问该成员(现在为空)字符串:

for_loop_buffer[buffer_pointer] = current_person[i]; // Illegal access!