使用wfstream和fstream打开同一个文件是否合适?

时间:2015-12-10 13:25:42

标签: c++ file

实际上我有一个要求,其中我需要在代码的一部分使用wfstream文件实例打开相同的文件,并在代码的其他部分使用fstream实例打开它。我需要访问一个文件,其中用户名是std :: wstring类型,密码是std :: string类型。如何在代码的同一部分中获取两个变量的值?  就像你在下面看到的那样,我需要从文件中获取用户名和密码的值,并将其分配给变量。 类型转换无法完成。请不要给出那个解决方案。 ...... file.txt的.......

用户名 - amritha 密码拉文

代码编写如下:

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


int main()
{


std::string y;
unsigned int l;
std::wstring username;
std::wstring x=L"username";
std::wstring q;
std::string password;
std::string a="password";



std::cout<<"enter the username:";
std::wcin>>username;
std::cout<<"enter the password:";
std::cin>>password;
std::wfstream fpp("/home/aricent/Documents/testing.txt",std::ios::in | std::ios::out );

std::getline(fpp,q);
if (q.find(x, 0) !=  std::string::npos) {

        std::wstring z=q.substr(q.find(L"-") + 1) ;
        std::wcout<<"the username is:"<<z; 
        fpp.seekg( 0, std::ios::beg ); 
            fpp<<q.replace(x.length()+1, z.length(), username); 



}

    fpp.close();
    std::fstream fp("/home/aricent/Documents/testing.txt",std::ios::in | std::ios::out );
    std::getline(fp,y);

if (y.find(a, 0) !=  std::string::npos)
 {

        unsigned int len=x.length()+1;
        unsigned int leng=username.length();
        l=len+leng;
        fp.seekg(l+1); 
        std::string b=y.substr(y.find("-") + 1) ;            
        fp<<y.replace(a.length()+1, b.length(), password);     

    }
    fp.close();
}

2 个答案:

答案 0 :(得分:0)

not recommended同时打开多个流到同一个文件。另一方面,如果您没有写入文件,但只是阅读(因此,将使用ifstreamwifstream),那可能是安全的。

或者,您只需打开wfstream,阅读用户名,关闭信息流,打开fstream并阅读密码。

如果您可以选择,请完全避免使用混合编码文件。

答案 1 :(得分:0)

您不应该尝试使用两个描述符打开同一个文件。即使它工作(例如只读模式),两个描述符也不会同步,所以你会在一个上读取第一个字符,在第二个上读下一个相同的字符。

所以恕我直言,你应该坚持一个单一的解决方案。我的建议是使用字符流来处理文件,并在需要时使用string从狭窄的wstring转换为宽std::wstring wconv(const std::string& str, const std::locale mylocale) { // define a codecvt facet for the locale typedef std::codecvt<wchar_t,char,std::mbstate_t> facet_type; const facet_type& myfacet = std::use_facet<facet_type>(mylocale); // define a mbstate to use in codecvt::in std::mbstate_t mystate = std::mbstate_t(); size_t l = str.length(); const char * ix = str.data(), *next; // narrow character pointers wchar_t *wc, *wnext; // wide character pointers // use a wide char array of same length than the narrow char array to convert wc = new wchar_t[str.length() + 1]; // conversion call facet_type::result result = myfacet.in(mystate, ix, ix + l, next, wc, wc + l, wnext); // should test for error conditions *wnext = 0; // ensure the wide char array is properly null terminated std::wstring wstr(wc); // store it in a wstring delete[] wc; // destroy the char array return wstr; }

示例转换函数可以是(ref:cplusplus.com: codecvt::in):

codecvt::out

此代码应测试异常情况,并使用try catch对异常免疫,但它留给读者练习: - )

使用nconv的上述变体可用于将宽字符串转换为窄字符串。

在上面的代码中,我会使用(假设codecvt::out是使用... #include <locale> ... std::cin>>password; std::locale mylocale; std::fstream fp("/home/aricent/Documents/testing.txt",std::ios::in | std::ios::out ); std::getline(fp,y); q = wconv(y, mylocale); ... fp<<nconv(q.replace(x.length()+1, z.length(), username)); } std::getline(fp, y); ... 将函数从宽字符串转换为窄字符串的函数):

>>> a = {"a":[1, 3, 10, 2, 5], "b":[1, 0, 0, 1, 14]}
>>> a
{'a': [1, 3, 10, 2, 5], 'b': [1, 0, 0, 1, 14]}