C++ 转换\\";换行符

C++ 转换\\";换行符,c++,C++,我一次解析一个字符的流,如下面高度简化的示例所示。我的问题是我需要将\\n转换为实际的换行符(对于任何其他转义字符也是如此) 有没有比我在这里用的手工方式更好的方法?因为如果我必须以这种方式转换所有可能的转义字符,那么这将变得相当麻烦 char c ; std::stringstream s("foo \\n bar") ; while (s.good()) { c = s.get() ; if (!s.good()) break ; if (c == '\\' &am

我一次解析一个字符的流,如下面高度简化的示例所示。我的问题是我需要将
\\n
转换为实际的换行符(对于任何其他转义字符也是如此)

有没有比我在这里用的手工方式更好的方法?因为如果我必须以这种方式转换所有可能的转义字符,那么这将变得相当麻烦

char c ;
std::stringstream s("foo \\n bar") ;

while (s.good()) {
    c = s.get() ;
    if (!s.good()) break ;
    if (c == '\\' && s.get() == 'n') c = '\n' ;
    std::cout << c ;
}
charc;
std::stringstreams(“foo\\n bar”);
而(s.good()){
c=s.get();
如果(!s.good())中断;
如果(c=='\'&&s.get()=='n')c='\n';

std::cout您的代码基本上是正确的,尽管我并不觉得它特别麻烦

但是,您的代码有一个错误:如果您将此作为输入:
“\\”,“g”
,则
g”字符将丢失,因为您没有保留第二个
s.get()`调用检索到的数据

我会这样做:

bool escaped = false;
while (s.good()) {
    c = s.get() ;
    if (!s.good()) break ;
    if( escaped ) {
        if( c == 'n' ) {
            std::cout << '\n' ;
        } else {
            std::cout << '\\' << c;
        }
        escaped = false;
    } else {
        if( c == '\\' ) {
            escaped = true;
        } else {
            std::cout << c ;
        }
    }
}
bool-escaped=false;
而(s.good()){
c=s.get();
如果(!s.good())中断;
如果(转义){
如果(c='n'){

std::cout您的代码基本上是正确的,尽管我并不觉得它特别麻烦

但是,您的代码有一个错误:如果您将此作为输入:
“\\”,“g”
,则
g”字符将丢失,因为您没有保留第二个
s.get()`调用检索到的数据

我会这样做:

bool escaped = false;
while (s.good()) {
    c = s.get() ;
    if (!s.good()) break ;
    if( escaped ) {
        if( c == 'n' ) {
            std::cout << '\n' ;
        } else {
            std::cout << '\\' << c;
        }
        escaped = false;
    } else {
        if( c == '\\' ) {
            escaped = true;
        } else {
            std::cout << c ;
        }
    }
}
bool-escaped=false;
而(s.good()){
c=s.get();
如果(!s.good())中断;
如果(转义){
如果(c='n'){
std::cout类似这样的内容:

int c;     // Not char.
while((c = s.get() != EOF)
{
    if (c == '\\')
    {
        switch(int escaped = s.get())
        {
           case 't':
              c = '\t';
              break;
           case 'n':
              c = '\n';
              break;
           case 'a':
              c = '\a';
           ...
           default:
              std::cout << c << escaped;    // Retain "invalid variants". 
              c = 0; 
              break;
        }
    }
    if (c)
    {
        std::cout << c;
    }
}
int c;//不是字符。
while((c=s.get()!=EOF)
{
如果(c=='\\')
{
开关(int-escape=s.get())
{
案例“t”:
c='\t';
打破
案例“n”:
c='\n';
打破
案例“a”:
c='\a';
...
违约:
std::cout类似这样的内容:

int c;     // Not char.
while((c = s.get() != EOF)
{
    if (c == '\\')
    {
        switch(int escaped = s.get())
        {
           case 't':
              c = '\t';
              break;
           case 'n':
              c = '\n';
              break;
           case 'a':
              c = '\a';
           ...
           default:
              std::cout << c << escaped;    // Retain "invalid variants". 
              c = 0; 
              break;
        }
    }
    if (c)
    {
        std::cout << c;
    }
}
int c;//不是字符。
while((c=s.get()!=EOF)
{
如果(c=='\\')
{
开关(int-escape=s.get())
{
案例“t”:
c='\t';
打破
案例“n”:
c='\n';
打破
案例“a”:
c='\a';
...
违约:

std::cout您基本上是在编写一个简单的lexer;手动执行此操作的常用方法是使用状态机

#include <iostream>
#include <stdexcept>
#include <sstream>
using namespace std;

int main() {
  char c;
  istringstream s("foo \\n bar");
  enum { CHARACTER, ESCAPE } state = CHARACTER;

  while (s.get(c)) {    
    switch (state) {
    case CHARACTER:
      if (c == '\\') {
        state = ESCAPE;
      } else {
        cout << c;
      }
      break;

    case ESCAPE:
      switch (c) {
      case 'n': cout << '\n'; break;
      case 't': cout << '\t'; break;
      default:
        throw runtime_error("unknown escape");
      }
      state = CHARACTER;
      break;
    }
  }
}
#包括
#包括
#包括
使用名称空间std;
int main(){
字符c;
IStringStreams(“foo\\n bar”);
枚举{字符,转义}状态=字符;
而(s.get(c)){
开关(状态){
大小写字符:
如果(c=='\\'){
状态=逃跑;
}否则{

cout您基本上是在编写一个简单的lexer;手动执行此操作的常用方法是使用状态机

#include <iostream>
#include <stdexcept>
#include <sstream>
using namespace std;

int main() {
  char c;
  istringstream s("foo \\n bar");
  enum { CHARACTER, ESCAPE } state = CHARACTER;

  while (s.get(c)) {    
    switch (state) {
    case CHARACTER:
      if (c == '\\') {
        state = ESCAPE;
      } else {
        cout << c;
      }
      break;

    case ESCAPE:
      switch (c) {
      case 'n': cout << '\n'; break;
      case 't': cout << '\t'; break;
      default:
        throw runtime_error("unknown escape");
      }
      state = CHARACTER;
      break;
    }
  }
}
#包括
#包括
#包括
使用名称空间std;
int main(){
字符c;
IStringStreams(“foo\\n bar”);
枚举{字符,转义}状态=字符;
而(s.get(c)){
开关(状态){
大小写字符:
如果(c=='\\'){
状态=逃跑;
}否则{

CUT< P>我不推荐它在C++中使用,但是这里有一些代码我在C 20年前写过,可能会提供一点灵感。
#include <string.h>
#include <stdio.h>

char *translate(char *string)
{
      char *here=string;
      size_t len=strlen(string);
      int num;
      int numlen;

      while (NULL!=(here=strchr(here,'\\')))
      {
            numlen=1;
            switch (here[1])
            {
            case '\\':
                  break;

            case 'r':
                  *here = '\r';
                  break;

            case 'n':
                  *here = '\n';
                  break;

            case 't':
                  *here = '\t';
                  break;

            case 'v':
                  *here = '\v';
                  break;

            case 'a':
                  *here = '\a';
                  break;

            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
                  numlen = sscanf(here,"%o",&num);
                  *here = (char)num;
                  break;

            case 'x':
                  numlen = sscanf(here,"%x",&num);
                  *here = (char) num;
                  break;
            }
            num = here - string + numlen;
            here++;
            memmove(here,here+numlen,len-num );
      }
      return string;
}
#包括
#包括
字符*翻译(字符*字符串)
{
char*here=string;
尺寸长度=strlen(字符串);
int-num;
国际努姆兰;
while(NULL!=(此处=strchr(此处,'\\'))
{
numlen=1;
开关(此处为[1])
{
案例“\\”:
打破
案例“r”:
*此处='\r';
打破
案例“n”:
*此处='\n';
打破
案例“t”:
*此处='\t';
打破
案例“v”:
*此处='\v';
打破
案例“a”:
*此处='\a';
打破
案例“0”:
案例“1”:
案例“2”:
案例“3”:
案例“4”:
案例“5”:
案例“6”:
案例“7”:
numlen=sscanf(此处为“%o”&num);
*这里=(char)num;
打破
案例“x”:
numlen=sscanf(此处为“%x”、&num);
*这里=(char)num;
打破
}
num=here-string+numlen;
here++;
memmove(这里,这里+numlen,lennum);
}
返回字符串;
}

> < P>我不推荐它在C++中使用,但是这里有一些代码我在C 20年前写过,可能会提供一点灵感。
#include <string.h>
#include <stdio.h>

char *translate(char *string)
{
      char *here=string;
      size_t len=strlen(string);
      int num;
      int numlen;

      while (NULL!=(here=strchr(here,'\\')))
      {
            numlen=1;
            switch (here[1])
            {
            case '\\':
                  break;

            case 'r':
                  *here = '\r';
                  break;

            case 'n':
                  *here = '\n';
                  break;

            case 't':
                  *here = '\t';
                  break;

            case 'v':
                  *here = '\v';
                  break;

            case 'a':
                  *here = '\a';
                  break;

            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
                  numlen = sscanf(here,"%o",&num);
                  *here = (char)num;
                  break;

            case 'x':
                  numlen = sscanf(here,"%x",&num);
                  *here = (char) num;
                  break;
            }
            num = here - string + numlen;
            here++;
            memmove(here,here+numlen,len-num );
      }
      return string;
}
#包括
#包括
字符*翻译(字符*字符串)
{
char*here=string;
尺寸长度=strlen(字符串);
int-num;
国际努姆兰;
while(NULL!=(此处=strchr(此处,'\\'))
{
numlen=1;
开关(此处为[1])
{
案例“\\”:
打破
案例“r”:
*此处='\r';
打破
案例“n”:
*此处='\n';
打破
案例“t”:
*此处='\t';
打破
案例“v”:
*此处='\v';
打破
案例“a”:
*此处='\a';
打破
案例“0”:
案例“1”:
案例“2”:
案例“3”:
案例“4”:
案例“5”:
案例“6”:
案例“7”:
numlen=sscanf(此处为“%o”&num);
*这里=(char)num;
打破
案例“x”:
numlen=sscanf(此处为“%x”、&num);
*这里=(char)num;
打破
}