无法忽略文本文件流中的转义字符,并存储在C++wchar_t [ ] 中



我正在尝试使用C++从文本文件中读取数据;将每一行的字符串存储到wchar_t[]或LPCWSTR中。(这两种数据类型是我工作的应用程序的约束。这就是为什么我必须将数据存储在这些数据类型中(

.txt文件中的数据格式为,例如:

abc\def\ghi 10
jkl\mnopq\rstq 20
aqq\sdsds\qc 30

我正在尝试逐行读取数据&将每一行保存为映射的键值对,其中key的类型为LPCWSTR或wchar_t[]类型&值为int类型提取int没有问题,但问题出现在读取字符串中

这是我的代码:

#include<iostream>
#include<fstream>
#include<windows.h>
#include<cstdlib>
using namespace std;
int main()
{
wchar_t test1[260];
const char* s = "Hello\ABC\DEF";
mbstowcs(test1, s, strlen(s));
wcout<<test1<<endl;

wchar_t gr[260];
string gr_temp;
int percentage;
ifstream ifs;
ifs.open("data.txt", ifstream::in);
if (ifs.is_open()) {
while (ifs >> gr_temp >> percentage){
const char* source = gr_temp.c_str();
mbstowcs(gr, source, strlen(source));
wcout<<gr<<L" ";
cout<<percentage<<endl;
}
ifs.close();
}
return 0;
}

然而,它给出了以下输出:

HelloABCDEFa
abc\def\ghi 10
jkl\mnopq\rstq 20
aqq\sdsds\qc 30
  1. 我不明白为什么在输出的第一行中突然出现了那个微小的"a">

  2. 我希望代码自动处理这些双斜杠,即我希望输出为:

    HelloABCDEF
    abcdefghi 10
    jklmnopqrstq 20
    aqqsdsdsqc 30
    
  3. 如果我能在.txt文件中不使用双斜杠&它们在不检查任何转义序列的情况下被自动处理。然而,由于上述第1(点中的问题存在,因此我不确定是否可能出现

  4. 即使将cout<<gr_temp<<endl;添加为while循环中的第一行,也会输出带有双后斜杠的字符串。

我错过了什么或做错了什么?

更新:

此外,当我在每个while循环的末尾使用语句m1[gr] = percentage;将这些键值对添加到std::map<LPCWSTR,int> m1时,使用print语句,它只显示映射中的一个元素。

我更新的代码是:

#include<iostream>
#include<fstream>
#include<windows.h>
#include<cstdlib>
#include<map>
using namespace std;
std::unordered_map<LPCWSTR, int>        m1;
int main()
{
wchar_t test1[260];
const char* s = "Hello\ABC\DEF";
mbstowcs(test1, s, strlen(s));
wcout<<test1<<endl;

wchar_t gr[260];
string gr_temp;
int percentage;
ifstream ifs;
ifs.open("data.txt", ifstream::in);
if (ifs.is_open()) {
while (ifs >> gr_temp >> percentage){
const char* source = gr_temp.c_str();
mbstowcs(gr, source, strlen(source));

m1[gr] = percentage;
}
ifs.close();
}
for (auto i = m1.begin(); i != m1.end(); i++) {
wcout<< i->first << L" ";
cout<< i->second << endl;
}
return 0;
}

这个代码只在地图中添加了一个元素&这是最近添加的元素。

我对代码进行了编辑,使用了unordered_map,但仍然存在相同的问题。

我进一步尝试打印地图的大小((。在这两种情况下,地图m1的大小都显示为1。

Miles Budnek已经说明了您的问题。

如果您查看函数的文档(http://www.cplusplus.com/reference/cstdlib/mbstowcs/),您将看到第三个参数并不期望转换为wchar_t的字节数,而是期望您所指向的缓冲区可以容纳的最大字符数。

一旦它找到\0(这恰好也是strlen正在寻找的(,它就会停止。

因此,只需将第一次mbstowcs调用的第三个参数替换为260(或sizeof(test1)/sizeof(wchar_t)(,您就可以很好地处理杂散的"a"。

如前所述,从文件中读取时不存在"转义参数"。这些仅存在于源代码中,表示无法键入的ASCII代码。(https://www.asciitable.com/)

\例如,n表示"新行"0x0A的代码符号。

因此,对文件中的反斜杠进行转义是不必要的,可以跳过。

如果您知道您的输入文件将有"双反斜杠",并且需要对其进行"unscape",则可以查看std::string函数"find"one_answers"replace"。

查找"\\"(一行中的两个反斜杠(并替换为"\"

针对您更新的问题(基本上是另一个问题(:问题是你为地图选择的钥匙。每个映射,无论是否无序,都需要唯一的密钥,在您的场景中,您可以继续使用相同的密钥。

LPCWSTR扩展为"指向宽字符字符串的指针",所以当您可能认为您使用"abc\def\ghi"作为键时,实际上您使用的是&gr[0],其在所有迭代期间保持不变。

另一个结果是,一旦程序离开gr的作用域,其内容将变为无效,并且访问映射(维护指针但不维护内容(将访问释放的内存,这往往会使程序崩溃。

这样的解决方案很简单:您需要使用内容作为键,而不是指针,例如使用std::wstring这样的容器对象。

最新更新