0

次のようなキーと値を含むテキスト ファイルがあります。

keyOne=1
keyTwo=734
keyThree=22.3
keyFour=5

キーは、私の例のように小文字と大文字だけです。値は整数または浮動小数点数です。各キーと値は等号 (=) で区切られています。ここで、プログラムにある変数に値を読み込みたいと思います。

これは、値を読み取ろうとしたコードです: (プログラムの変数に値を格納する部分を省略し、デモンストレーションのためにそれらを印刷するだけです。)

std::fstream file(optionsFile, std::fstream::in);

if (file.good()) {
  int begin;
  int end;
  std::string line;

  while(std::getline(file, line)) {

    // find the position of the value in the line
    for (unsigned int i = 0; i < line.length(); i++) {
      if (line.at(i) == '=') {
        begin = i + 1;
        end = line.length();
        break;
      }
    }

    // build the string... it starts at <begin> and ends at <end>
    const char *string = "";
    for (int i = begin; i < end; i++) {
      string += line.at(i);
    }

    // only gibberish is printed in the following line :(
    std::cout << "string=" << string << std::endl;
  }
}

値が出力されない理由がわかりません..代わりに、奇妙なものだけが出力されるか、何も出力されません

これが私の精神をとても激しく壊したのを助けてください:(

4

2 に答える 2

1

メモリを適切に割り当てずに C スタイルの文字列 (char 配列) を使用しており、ポインタで操作しているだけなので、文字列に文字を追加していません。

   // build the string... it starts at <begin> and ends at <end>
const char *string = "";
for (int i = begin; i < end; i++) {
  string += line.at(i);
}

std::string代わりに使用してください:

/// build the string... it starts at <begin> and ends at <end>
std::string str;
for (int i = begin; i < end; i++) {
  str += line.at(i);
}

または、手動でメモリを割り当て、適切なインデックスを使用し、文字列を '\0' 文字で終了し、不要になった文字列を削除することを忘れないでください。

char *string = new char[end - begin + 1];
int j = 0;
for (int i = begin;  i < end; i++) {
  string[j++] = line.at(i);
}

// Don't forget to end the string!
string[j] = '\0';

// Don't forget to delete string afterwards!
delete [] string;

だから、ただ使ってstd::stringください。

編集なぜC文字列とstd::stringそもそも混ぜたのですか?

于 2013-08-24T15:46:26.887 に答える
1

既に述べたように、c/c++ のネイティブ文字列型は、基本的に事前に割り当てられたメモリへのポインターであるため、単純な連結をサポートしていません。文字列が変更可能であると想定される場合は、常に std::string を使用する必要があります。

ところで、次のリファクタリングについて考えてみてください。

void process_option (const std::string& a_key, const std::string& a_value)
{
    std::cout << a_key << " <-- " << a_value << std::endl;
}

void read_options (std::istream& a_in, const char* a_source)
{
    int line_n = 0;
    std::string line;
    while (std::getline(a_in, line))
    {
        ++ line_n;
        std::string::size_type p = line. find('=');
        if (p == line. npos)
        {
        //  invalid_entry(a_source, line_n);
            continue;
        }

        process_option(
            line. substr(0, p), // key
            line. substr(p + 1, line. find_first_of("\t\r\n", p + 1)) // value
        );
    }
}

void read_options (const char* a_filename)
{
    std::ifstream file(a_filename);
    if (! file)
    {
    //  read_error(a_filename);
        return;
    }
    read_options(file, a_filename);
    file. close();
}

void read_options (const std::string& a_filename)
{
    read_options(a_filename. c_str());
}
于 2013-08-24T16:31:45.233 に答える