【问题标题】:C++ Output: std::cout and file output have not the same contentC++ 输出:std::cout 和文件输出的内容不同
【发布时间】:2017-04-25 22:59:58
【问题描述】:

这是我的代码:

//main.cpp

#include <iostream>
#include <fstream>  //files
#include <string>   //strings
#include <sstream>  //stringstreams

string intToString(int wert){
    ostringstream strout;
    string str;
    strout<<wert;
    str=strout.str();
    return str;}

int stringToInt(string str){
    istringstream strin;
    unsigned long long intVar;
    strin.str(str);
    strin>>intVar;
    return intVar;}

string wordsToAscii(string wort){
    string hold;
    for(int j=0;j<wort.length();j+=3){
        for(int i=j;i<j+3;i++){
            if(int(wort[i]>=100))
                hold=hold+intToString(int(wort[i]));
            if(int(wort[i]>=10 && wort[i]<=99))  
                hold=hold+"0"+intToString(int(wort[i]));
            if(int(wort[i]<=9))
                hold=hold+"00"+intToString(int(wort[i]));
        }
    }
    return hold;
}

string AsciiToWords(string wort){
    string hold;
    string total;
    for(int j=0;j<wort.length();j+=15)
        for(int i=j;i<j+15;i+=3){
            hold="\0";
            for(int k=i;k<i+3;k++)
                hold+=wort[k];
            if(hold=="000")
                break;
            total+=stringToInt(hold);
        }
    return total;
}

int main(){

    string str;

    ifstream f ("input");
    ofstream g ("temp");
    while(!f.eof())
        if(getline(f,str)){
            cout<<wordsToAscii(str)<<"\n";
            g<<wordsToAscii(str)<<"\n";}
    f.close();
    g.close();

    ifstream h ("temp");
    ofstream i ("output");
    while(!h.eof())
        if(getline(h,str)){
            cout<<AsciiToWords(str)<<"\n";
            i<<AsciiToWords(str)<<"\n";}
    h.close();
    i.close();

    return 0;
}

输入:(文件)

first line test1
second line test2
last line test3
testA testB testC
one
two

临时:(文件)

102105114115116032108105110101032116101115116049000000
115101099111110100032108105110101032116101115116050000
108097115116032108105110101032116101115116051
116101115116065032116101115116066032116101115116067000
111110101
116119111

输出:(文件)

first line test1
second line test2
last line test3
testA testB testC
one

输出:(在终端中)

102105114115116032108105110101032116101115116049000000
115101099111110100032108105110101032116101115116050000
108097115116032108105110101032116101115116051
116101115116065032116101115116066032116101115116067000
111110101
116119111
first line test1
second line test2
last line test3
testA testB testC
oneA
twoA

第一个函数将字符转换为其对应的 ASCII 数字。 第二个应该把它转换回来。

这两个功能似乎运作良好。问题是文件和终端中的输出不同。唯一的区别是cout&lt;&lt; 而不是i&lt;&lt;

此外,在输入不同的情况下,有时最后一行会被写入两次,或者根本不写入。我自己无法解释。我研究了几个小时,改变了读取/写入文件的方式,重写了部分代码等,但没有找到原因

提前感谢您的帮助

【问题讨论】:

  • 小心你的麦芽汁[i]。在您的代码中,“i”可以大于麦汁长度。
  • stringToIntintToString 是什么?
  • 即使代码有问题...如何解释不同的输出?

标签: c++ file input output cout


【解决方案1】:

eof() 仅在尝试从文件末尾读取失败后才返回 true,当您使用错误的构造 while(!eof()) 时,您的代码会在循环中进行额外的迭代。

在此迭代之后,您已读取的变量中有垃圾。当您将数据打印到控制台和文件时,这种垃圾是不同的,这就是您看到不同输出的原因

asciiToWords 和 wordsToAscii 函数也存在一些问题,经过一些更改后可以正常工作:

//main.cpp

#include <iostream>
#include <fstream>  //files
#include <string>   //strings
#include <sstream>  //stringstreams

using namespace std;

string intToString(int wert){
    ostringstream strout;
    string str;
    strout<<wert;
    str=strout.str();
    return str;}

int stringToInt(string str){
    istringstream strin;
    unsigned long long intVar;
    strin.str(str);
    strin>>intVar;
    return intVar;}

string wordsToAscii(string wort){
    string hold;
    for(int i=0;i<wort.length();i++){
            if(int(wort[i]>=100))
                hold=hold+intToString(int(wort[i]));
            if(int(wort[i]>=10 && wort[i]<=99))  
                hold=hold+"0"+intToString(int(wort[i]));
            if(int(wort[i]<=9))
                hold=hold+"00"+intToString(int(wort[i]));
    }
    return hold;
}

string AsciiToWords(string wort){
    string hold;
    string total;
    for(int j=0;j<wort.length();j+=3)
    {
        hold="";
        for(int i=j;i<j+3;i++)
            hold+=wort[i];
        total+=stringToInt(hold);
    }    
    return total;
}

int main(){

    string str;

    ifstream f ("input");
    ofstream g ("temp");
    while(getline(f,str))
    {
            cout<<wordsToAscii(str)<<"\n";
            g<<wordsToAscii(str)<<"\n";
    }
    f.close();
    g.close();

    ifstream h ("temp");
    ofstream i ("output");
    while(getline(h,str))
    {
            cout<<AsciiToWords(str)<<"\n";
            i<<AsciiToWords(str)<<"\n";
    }
    h.close();
    i.close();

    return 0;
}

【讨论】:

  • 这意味着我应该使用while(getline(h,str)) 吗?它提供与以前相同的输出。最后一行“二”根本没有打印出来……
  • asciiToWords 和 wordsToAscii 函数到底是做什么的?
  • "第一个函数将字符转换成它们对应的 ASCII 数字。第二个函数应该把它转换回来。" Hello = 072-101-108-108-111-000 。附加零以使 length()%9==0 为真
  • 为什么wordsToAscii在第3步使用循环,如果字符串长度不除以3怎么办?
  • 两个第一个字符串的长度如果文件输入不同,所以“temp”中两个第一个字符串的长度也应该不同,但它们是相同的,所以“wordsToAscii”中肯定有问题
【解决方案2】:

我纠正了一些错误,这个版本对我有用。我尽量尊重你的做法,虽然觉得有点奇怪

我删除了 intToString 和 stringToInt 函数。改为使用字符串中的 to_string 静态函数。 我删除了 wordsToAscii 和 AsciiToWords 函数中的双循环,因为它们没有用,而且更难看到发生了什么

我认为这里的主要问题是读取文件的方式,只需执行一段时间(getline(h,str)) 就足以读取它直到另一条评论指出的结尾。

希望有帮助!

string wordsToAscii(string wort){
    string hold;
    int ascii_value;

    for(int i=0 ; i < wort.length() ; i++){
        char car = wort[i];
        ascii_value = int(car);

        if( ascii_value >=100)
                hold=hold+ to_string(ascii_value);
        else if( ascii_value >=10 &&  ascii_value <=99)
                hold += "0"+ to_string(ascii_value);
        else
                hold += "00"+ to_string(ascii_value);
    }
    return hold;
}

string AsciiToWords(string wort){
    string hold;
    string total;
    int ascii_value;
    char car;

    for(int i=0 ; i<wort.size() ; i+=3){
        hold ="";
        for(int k=i;k<i+3;k++)
            hold+=wort[k];

        ascii_value = atoi(hold.c_str()); // Conversion of the string "105" to value 105
        car = ascii_value; //Conversion of the value 105 to corresponding ASCII character 'f'
        total += car;//Concatenate the character 'f' to string
    }
    return total;
}

int main(){

    string str;

    ifstream f ("C:\\input.txt");

    if(!f.is_open()){
        cout << "File not opened " << endl;
        return 0;
    }

    ofstream g ("temp");
    while(getline(f,str)){
        cout << wordsToAscii(str) << "\n";
        g<<wordsToAscii(str)<< "\n";
    }
    f.close();
    g.close();

    ifstream h ("temp");
    ofstream i ("output");
    while(getline(h,str)){
            cout << AsciiToWords(str) << "\n";
            i << AsciiToWords(str) << "\n";
    }
    h.close();
    i.close();

    return 0;
}

【讨论】: