2

いくつかの文字列を連結しようとしていますが、ある文字列では機能しますが、別の文字列では機能しません。

作業: 2 つの引数を取り、これを実行します。a = こんにちは、b = 世界

string concat = a + b;

出力は問題なく hello world になります。

機能しない: ファイルから読み取り、2 番目の引数と連結します。ファイルからの文字列がabcdefgであると仮定します。

string concat = (string from file) + b;

そしてそれは私にworldfgを与えます。

連結する代わりに、b からの文字列が最初の文字列を上書きします。

stringstream を使用するなど、他のいくつかの方法を試しましたが、うまくいきません。

これは私のコードです。

int main (int nArgs, char *zArgs[]) {
    string a = string (zArgs [1]);
string b = string (zArgs [2]);
    string code;

    cout << "Enter code: ";
cin >> code;

    string concat = code + b;
}
// The output above gives me the correct concatenation.
// If I run in command prompt, and do this. ./main hello world
// then enters **good** after the prompt for code.
// The output would be **goodworld**

ただし、ファイルからいくつかの行を読み取りました。

 string f3 = "temp.txt";
 string r;
 string temp;

 infile.open (f3.c_str ());

 while (getline (infile, r)) {
    // b is take from above
temp = r + b;
    cout << temp << endl;
 }
 // The above would give me the wrong concatenation.
 // Say the first line in temp.txt is **quickly**.
 // The output after reading the line and concatenating is **worldly**

より明確な例が得られることを願っています。

アップデート:

問題の原因がテキスト ファイルにあることがわかったのではないかと思います。内部にいくつかのランダムな行を含む新しいテキスト ファイルを作成しようとしましたが、正常に動作しているようです。しかし、元のファイルを読み取ろうとすると、間違った出力が返されます。まだこれに頭を悩ませようとしています。

次に、元のファイルの内容を新しいファイルにコピーしようとしましたが、うまく機能しているようです。ただし、ここで何が問題なのかよくわかりません。引き続きテストを行いますが、うまくいくことを願っています。

助けてくれてありがとう!感謝します!

4

2 に答える 2

3

元の質問をしたチャップと同じ出力が得られます。

$ ./a.out hello world
Enter code: good
goodworld
worldly

ここで問題になるのは、テキスト ファイルの内容です。私の例では、テキスト ファイルの最初の 7 文字は "quickly" です。ただし、その直後に 7 つのバックスペース バイト (hex 08) が続きます。これは、内容が emacs でどのように見えるかです:

quickly^H^H^H^H^H^H^H

では、これがどのように混乱を引き起こしているのでしょうか。

連結操作は実際には正しく機能します。もしあなたがそうするなら:

std::cout << "string length: " << temp.size() << "\n";

19... 「quickly」(7) + 7 つのバックスペース文字 + 「world」(5) で構成される答えが得られます。この 19 文字の文字列をコンソールに出力すると、上書き効果が発生します。バックスペース シーケンスを「カーソルを左に戻す」ことを意味するものとして解釈するのはコンソール (xterm など) であり、以前の文字は削除されます。代わりに出力をファイルにパイプすると、完全な文字列 (バックスペースを含む) が実際に生成されることがわかります。

これを回避するには、ファイルからの入力を検証/修正する必要があります。C/C++ 環境で一般的に利用できる関数など、利用できる関数がありますisprint(int c), iscntrl(int c)

更新: 別の応答者が述べたように、他の ASCII 制御文字も同じ効果があります。たとえば、キャリッジ リターン (Hex 0D) もカーソルを左に戻します。

于 2012-10-27T09:11:44.673 に答える
1

これをコンパイルすると

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main (int nArgs, char *zArgs[]) {
   string a = string (zArgs [1]);
   string b = string (zArgs [2]);
   string code;

   cout << "Enter code: ";
   cin >> code;

   string concat = code + b;
   // The output above gives me the correct concatenation.

   //However, I read some lines from the file.
   ifstream infile;

   string f3 = "temp.txt";
   string r;
   string temp;

   infile.open (f3.c_str ());

   while (getline (infile, r)) {
      temp = r + code;
      cout << temp << endl;
   }
   // The above would give me the wrong concatenation.
   infile.close();
   return 0;
}

コンパイルして問題なく実行されます。これはあなたのコンピュータで何をしますか?失敗した場合は、の内容を比較する必要がありますtemp.txt

(これは回答ではなくコメントである必要がありますが、長すぎます。申し訳ありません。)

于 2012-10-27T07:17:15.420 に答える