Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func configure(scanner *bufio.Scanner) {
	scanner.Split(bufio.ScanWords)
	scanner.Buffer(make([]byte, 1000005), 1000005)
}
func getNextString(scanner *bufio.Scanner) string {
	scanned := scanner.Scan()
	if !scanned {
		panic("scan failed")
	}
	return scanner.Text()
}
func getNextInt(scanner *bufio.Scanner) int {
	i, _ := strconv.Atoi(getNextString(scanner))
	return i
}
func getNextInt64(scanner *bufio.Scanner) int64 {
	i, _ := strconv.ParseInt(getNextString(scanner), 10, 64)
	return i
}
func getNextFloat64(scanner *bufio.Scanner) float64 {
	i, _ := strconv.ParseFloat(getNextString(scanner), 64)
	return i
}
func main() {
	fp := os.Stdin
	wfp := os.Stdout
	extra := 0
	if os.Getenv("I") == "IronMan" {
		fp, _ = os.Open(os.Getenv("END_GAME"))
		extra = 100
	}
	scanner := bufio.NewScanner(fp)
	configure(scanner)
	writer := bufio.NewWriter(wfp)
	defer func() {
		r := recover()
		if r != nil {
			fmt.Fprintln(writer, r)
		}
		writer.Flush()
	}()
	solve(scanner, writer)
	for i := 0; i < extra; i++ {
		fmt.Fprintln(writer, "-----------------------------------")
		solve(scanner, writer)
	}
}
func solve(scanner *bufio.Scanner, writer *bufio.Writer) {
	for s, c := getNextString(scanner), getNextString(scanner); c != "X"; s, c = getNextString(scanner), getNextString(scanner) {
		if strings.Index(s, "_") != -1 {
			fmt.Fprintln(writer, translate(strings.Split(s, "_"), c))
			continue
		}
		ss := make([]string, 0)
		for len(s) > 0 {
			index := nextupper(s[1:])
			ss = append(ss, s[:index+1])
			s = s[index+1:]
		}
		fmt.Fprintln(writer, translate(ss, c))
	}
}
func translate(ss []string, c string) string {
	switch c {
	case "U":
		return u(ss)
	case "L":
		return l(ss)
	case "D":
		return d(ss)
	}
	return ""
}

func nextupper(s string) int {
	n := len(s)
	for i := 0; i < n; i++ {
		if s[i:i+1] == strings.ToUpper(s[i:i+1]) {
			return i
		}
	}
	return n
}
func u(ss []string) string {
	n := len(ss)
	for i := 0; i < n; i++ {
		ss[i] = fmt.Sprintf("%s%s", strings.ToUpper(ss[i][0:1]), ss[i][1:])
	}
	return strings.Join(ss, "")
}
func l(ss []string) string {
	n := len(ss)
	ss[0] = strings.ToLower(ss[0])
	for i := 1; i < n; i++ {
		ss[i] = fmt.Sprintf("%s%s", strings.ToUpper(ss[i][0:1]), ss[i][1:])
	}
	return strings.Join(ss, "")
}
func d(ss []string) string {
	n := len(ss)
	for i := 0; i < n; i++ {
		ss[i] = strings.ToLower(ss[i])
	}
	return strings.Join(ss, "_")
}

C++: #include <algorithm>
#include <iostream>
#define between(a,x,b) ((a)<=(x)&&(x)<=(b))
using namespace std;

int main(){
  int i=0;
  string s,t;
  for(;cin >> s >> t,t!="X";){
  if(find(s.begin(),s.end(),'_')!=s.end()){
    for(i=0;i<s.length();i++)
      if(s[i]=='_'){
        if(s[i+1]=='_'||s[i+1]==0){cout << "Error!" << endl;return 0;}
        s.erase(i,1),s[i]-=0x20;
      }
    if(t=="U")s[0]-=0x20;
    cout << s << endl;
  }else{
    if(t=="U")s[0]-=0x20;
    else if(t=="L")s[0]+=0x20;
    else for(i=0;i<s.length();i++)
      if(between('A',s[i],'Z')){
        if(i)s.insert(i,1,'_');
        s[++i]+=0x20;
      }
    cout << s << endl;
  }
  }
}

C++: #include <iostream>
#include <string>
using namespace std;
int main(){
  int i,len,flag;
  char type;
  string name,out;
  while(1){
    flag=0;
    out="";
    cin >> name >> type;
    if(type=='X') break;
    len=name.size();
    for(i=0;i<len;i++){
      if(i==0){
	if(name[i]<'a'&&type!='U') out+=name[i]-'A'+'a';
	else if(name[i]>='a'&&type=='U') out+=name[i]-'a'+'A';
	else out+=name[i];
      }
      else{
	if(name[i]<'a'||name[i]=='_') flag=1;
	if(name[i]=='_'&&type!='D'){
	  out+=name[i+1]-'a'+'A';
	  i++;
	}
	else if(name[i]<'a'&&type=='D'){
	  out+='_';
	  out+=name[i]-'A'+'a';
	}else out+=name[i];
      }
    }
    if(type=='L'&&flag==0) out[0]=out[0]-'a'+'A';
    cout << out << endl;
  }
  return 0;
}

C++: #include <bits/stdc++.h>

using namespace std;

template <typename T>
using vec1 = vector<T>;

template <typename T>
T cin2var()
{
    T val;
    cin >> val;
    return val;
}

template <typename Iterator>
string Join(const Iterator& cbegin, const Iterator& cend, const string& delim = "")
{
    ostringstream os;
    copy(cbegin, cend, ostream_iterator<string>(os, delim.c_str()));
    string str(os.str());
    if (!str.empty()) {
        str.erase(str.size() - delim.size());
    }
    return str;
}

bool matchWordsByUS(const string& str, vec1<string>& words)
{
    int   start = 0;
    regex ptn("_|$");
    for (sregex_iterator ite(str.cbegin(), str.cend(), ptn), end; ite != end; ++ite) {
        auto&&     m(*ite);
        const auto word(str.substr(start, m.position() - start));
        if (str == word) break;
        if (word.empty()) continue;
        words.push_back(word);
        start = m.position() + 1;  // マッチ箇所を含まない
    }
    return !words.empty();
}

bool matchWordsByCC(const string& str, vec1<string>& words)
{
    int   start = 0;
    regex ptn("[A-Z]|$");
    for (sregex_iterator ite(str.cbegin(), str.cend(), ptn), end; ite != end; ++ite) {
        auto&&     m(*ite);
        const auto word(str.substr(start, m.position() - start));
        if (word.empty()) continue;
        words.push_back(word);
        start = m.position();
    }
    return !words.empty();
}

void ConvUCC(vec1<string>& words)
{
    for (auto& word : words) {
        char& c(word.front());
        c = toupper(c);
    }
}

void ConvLCC(vec1<string>& words)
{
    for (auto ite(words.begin()); ite != words.end(); ++ite) {
        char& c(ite->front());
        if (ite == words.begin()) {
            c = tolower(c);
        }
        else {
            c = toupper(c);
        }
    }
}

void ConvUS(vec1<string>& words)
{
    for (auto& word : words) {
        char& c(word.front());
        c = tolower(c);
    }
}

int main()
{
    while (true) {
        const auto N(cin2var<string>());
        const auto T(cin2var<string>());
        const char t(T.front());
        if (t == 'X') break;
        vec1<string> words;
        matchWordsByUS(N, words) || matchWordsByCC(N, words);
        switch (t) {
        case 'U':
            ConvUCC(words);
            cout << Join(words.cbegin(), words.cend()) << endl;
            break;
        case 'L':
            ConvLCC(words);
            cout << Join(words.cbegin(), words.cend()) << endl;
            break;
        case 'D':
            ConvUS(words);
            cout << Join(words.cbegin(), words.cend(), "_") << endl;
            break;
        default:
            break;
        }
    }
    return 0;
}

C++: #include <iostream>
#include <complex>
#include <sstream>
#include <string>
#include <algorithm>
#include <deque>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <vector>
#include <set>
#include <limits>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <ctime>
using namespace std;
#define REP(i, j) for(int i = 0; i < (int)(j); ++i)
#define FOR(i, j, k) for(int i = (int)(j); i < (int)(k); ++i)
#define SORT(v) sort((v).begin(), (v).end())
#define REVERSE(v) reverse((v).begin(), (v).end())
typedef complex<double> P;

string ULtoD(string s){
  stringstream ss;
  ss << (char)tolower(s[0]);
  FOR(i, 1, s.length()){
    if(isupper(s[i])) ss << '_' << (char)tolower(s[i]);
    else ss << s[i];
  }
  return ss.str();
}

string DtoUL(string s, char t){
  stringstream ss;
  ss << (char)(t == 'U' ? toupper(s[0]) : s[0]);
  FOR(i, 1, s.length()){
    if(s[i] == '_') ss << (char)toupper(s[++i]);
    else ss << s[i];
  }
  return ss.str();
}

int main() {
  string s; char t;
  while(cin >>s >>t && t != 'X'){
    char bt;
    if(isupper(s[0])) bt = 'U';
    else if(s.find('_') != string::npos) bt = 'D';
    else bt = 'L';
    if(bt == 'U'){
      if(t == 'L') s[0] = tolower(s[0]);
      if(t == 'D') s = ULtoD(s);
    } else if(bt == 'L'){
      if(t == 'U') s[0] = toupper(s[0]);
      if(t == 'D') s = ULtoD(s);
    } else s = DtoUL(s, t);
    cout <<s <<endl;
  }
  return 0;
}