Converter nomes de cabeçalho C em nomes de cabeçalho C ++


27

Na biblioteca padrão C, os nomes dos cabeçalhos terminam com um .hsufixo:

stdio.h

No C ++, esses nomes de cabeçalho estão disponíveis em um formato alternativo, com um cprefixo:

cstdio

Escreva uma função que converta o primeiro formulário no segundo. Você pode fazer a conversão no local ou deixar a string original intacta e retornar uma nova string. O que quer que pareça natural no seu idioma de escolha.

O código deve ser compilado / interpretado sem erros. Avisos do compilador são aceitáveis.

Aqui está sua solução C de linha de base. Possui 70 caracteres e gera um aviso sobre strlen:

void f(char*h){int i=strlen(h);h[--i]=0;while(--i)h[i]=h[i-1];*h='c';}

A solução mais curta (medida em número de caracteres) vence.

Atualização: se o seu idioma de escolha não suportar funções, programas inteiros também serão aceitáveis.

Atualização: Conforme sugerido por FUZxxl, aqui está uma lista completa dos arquivos de cabeçalho na biblioteca padrão C:

assert.h
ctype.h
errno.h
float.h
limits.h
locale.h
math.h
setjmp.h
signal.h
stdarg.h
stddef.h
stdio.h
stdlib.h
string.h
time.h

Especificamente, não há nomes de cabeçalho com vários pontos.

Respostas:


37

Código da máquina 80386, 13 bytes

Hexdump do código:

b0 63 86 01 41 3c 2e 75 f9 c6 01 00 c3

Código fonte (pode ser compilado pelo Visual Studio):

__declspec(naked) void __fastcall conv(char s[])
{
    _asm {
        mov al, 'c';            // b0 63
    myloop:
        xchg al, [ecx];         // 86 01
        inc ecx;                // 41
        cmp al, '.';            // 3c 2e
        jne myloop;             // 75 f9
        mov byte ptr [ecx], 0;  // c6 01 00
        ret;                    // c3
    }
}

Ele converte a string no local. O código é tão simples que não é necessário salvar e restaurar registros (usando apenas ale ecx, que a fastcallconvenção permite derrotar).


Nice, este me leva de volta :)
fredoverflow

Definitivamente uma das soluções mais legais! Mas o código fonte não tem 13 bytes, apenas a forma compilada (que eu acho que poucos de nós gostariam de escrever em um editor hexadecimal).
Per Lundberg

3
Dê a ele sua vitória. Byte = caractere é uma interpretação perfeitamente razoável aqui.
Joshua

7
@PerLundberg Eu vejo o código fonte neste caso como a explicação expandida / comentada "como funciona" que muitas pessoas incluem em seus idiomas ultracompactos. Para um programa tão pequeno, poderia muito bem ter sido escrito à mão. :)
macio

@ Ponto justo macio. E sim, o número de pessoas que poderiam escrever o código binário de cor é certamente> 0, mesmo que eu não conheça ninguém que seja nerd. ;)
Por Lundberg,


14

CJam, 6 bytes

'clW(<

Este é um programa completo que lê a string via STDIN

Explicação :

'c               "Put character c on stack";
  l              "Read a line from STDIN";
   W             "W is a predefined variable with value -1";
    (            "Decrease the value by 1";
     <           "Remove last 2 characters from the string on stack, the input argument";

Experimente online aqui


Não é -2tão bom quanto W(?
Esolanging Fruit


11

brainfuck - 25 23 bytes

,[>,]<-----.<,<[<]>[.>]

Se o seu idioma de escolha não suportar funções, programas inteiros também serão aceitáveis.

Este é um programa completo que recebe informações do STDIN.

,[>,]      get all bytes of input
<-----.    subtract 5 from last byte (always "h"; "h" minus 5 = "c") and print result
<,         set second last byte to 0 by abusing comma
<[<]>      go to first byte
[.>]       print byte and move right until hitting 0

Isso não
sairia

@feersum Se o seu intérprete permite que você saia da borda esquerda, sim. Todo mundo que eu já usei prende a fita.
Undergroundmonorail

2
@feersum Se você quiser experimentá-lo, mas seu intérprete permite que você caia, você pode corrigi-lo com um >no início.
Undergroundmonorail

10

Haskell - 23 caracteres

('c':).takeWhile(/='.')

Haskell - 16 caracteres, conforme sugerido por nimi

('c':).init.init

2
Se você soltar os 2 últimos caracteres, em init.initvez de colocar todos no primeiro, .economiza alguns bytes.
nimi

@nimi Essa é uma sugestão incrível!
Fredoverflow 12/02/2019

10

C, 38

Veja em Ideone

f(s,o){snprintf(o,strlen(s),"c%s",s);}

sé um ponteiro para a sequência de entrada e oé para onde a saída deve ser gravada.

Eu encontrei uma maneira de abusar snprintf. A string de saída passa a ser convenientemente um caractere menor que a entrada, e o comprimento máximo da string escrita por snprintfé 1 menor que o nargumento, portanto, corta o .h. Nota: esta técnica não funcionará com a implementação da Microsoft porque faz a coisa errada e falha ao finalizar a string com nulo.


8

Arquivo em lote do Windows 11

@echo c%~n1

O primeiro parâmetro transmitido é% 1. O modificador ~ n retorna apenas o nome do arquivo sem extensão.

Se for aceitável repetir o comando expandido na tela também, o @ inicial pode ser removido.


8

Arquitetura do tipo T21 do nó TIS - 85 bytes

Esta resposta é apenas por diversão; a linguagem surgiu depois que esse desafio foi escrito e, portanto, não posso vencer com ele. (Não que eu fosse.)

Ok, eu me diverti um pouco com este. Eu provavelmente deveria chamar a linguagem "TIS-100", mas por que quebrar caracteres? : D

O TIS-100 é um jogo sobre a programação de um computador com uma arquitetura totalmente única e bizarra. Eu escrevi um quebra-cabeça personalizado para esse desafio, o que me permite receber e verificar a saída em relação a uma "string" correta e conhecida. Infelizmente, não há como lidar com seqüências de caracteres ou caracteres, portanto este programa simplesmente usa o valor ASCII de cada caractere para entrada e saída.

Se você gostaria de vê-lo em ação, você pode usar este emulador , ou apenas assista-me a executá-lo no jogo real aqui . Observe que no vídeo, a linha final do primeiro nó é D:MOV UP NIL. Depois de terminar o vídeo, percebi que podia jogar até o fim D:ADD UP. Funcionalmente, não há diferença, porque o valor do ACC é imediatamente substituído de qualquer maneira.

Esta é a string que usei para minha contagem de bytes:

MOV 99 ANY
MOV -46 ACC
ADD UP
JEZ D
ADD ACC ANY
JRO -5
D:ADD UP
MOV UP ANY
MOV UP ANY

Esse é o texto de cada nó não vazio, separado por novas linhas (adicionando efetivamente 1 byte para cada nó usado além do primeiro, espelhando nossa regra sobre o código em vários arquivos).


7

Dyalog APL (8 caracteres)

'c',¯2↓⊢

Essa solução é exatamente a mesma que a solução J que enviei, mas usa um caractere a menos por ser um caractere a menos que }..


7

J (9 caracteres)

'c',_2}.]
  • |yé a magnitude de y(também chamado valor absoluto)
  • x }. ydescarta |xitens de y; os itens são descartados da frente, se xpositivo, e do final, se xnegativo.
  • x , yacrescenta xe y.
  • 'c' , _2 }. yfaz a transformação que você deseja; em notação tácita, isso pode ser expresso como 'c' , _2 }. ].

7

Avestruz 0.6.0 , 8 caracteres

););"c\+

)é o operador "uncons direito". Quando aplicado a uma string, ele se transforma, por exemplo, `foo`em `fo` `o`. ;é usado para destacar o caractere extra, e isso é feito novamente.

Então, "cé empurrado. Isto é simplesmente uma abreviação de `c`.

\+ troca os dois principais elementos da pilha e os concatena.


Este idioma foi criado por você?
Ismael Miguel


Eu acho que sim. Eu já verifiquei, portanto, pensando nisso. Não há referência a esse idioma em nenhum lugar. Só aqui. Então, eu assumi que foi feito por você. Para um garoto de 14 anos, você foi muito longe na programação. +1000 para isso!
Ismael Miguel

@IsmaelMiguel Opa, desculpe, deveria ter lhe dito que eu sou o KeyboardFire no Github. Obrigado!
Maçaneta

Você não precisa. Está quase implícito. Sou ismael-miguel (muito original, acesse github.com/ismael-miguel ). Não tenho nada interessante e útil lá, mas você pode conferir. Mas estou interessado no seu idioma. A única coisa completa é a classe UIntArray para php ( github.com/ismael-miguel/php-uintarray, se você estiver interessado).
Ismael Miguel

7

piet ( 9x11 = 99 8X11 = 88)

v2

outra tentativa (2x37 = 74)

insira a descrição da imagem aqui

Difícil torná-lo muito menor, pois precisa gerar um 99 ('c') e um 46 ('.'), E isso exige espaço na pena.


1
Piet nunca medido em caracteres, apenas codels, assim você não precisa mencionar os 0 caracteres mordeu :) Também isso é um monte de branco
SP3000

tentando comprimir, mas é um pouco difícil. Tendo problemas para finalizar se eu remover mais uma linha ou coluna.
Captncraig

Isso é um pouco de trapaça, mas eu gosto. É como usar /dev/nullcomo seu código-fonte.
Ismael Miguel

2
De acordo com o META ( meta.codegolf.stackexchange.com/questions/4782/… ), seu programa não precisa terminar. Desde que seja tarefa, seu programa pode ser executado para sempre. Leia a primeira resposta para a pergunta.
Ismael Miguel

6

F # - 39. 37. 31

31 - Porque a digitação em rochas F #!

fun s->("c"+s).Replace(".h","")

37.

fun(s:string)->"c"+s.Replace(".h","")

39.

fun(s:string)->"c"+s.Remove(s.Length-2)

Não funciona para um cabeçalho chamado foo.hoo.h.
FUZxxl

3
@FUZxxl Não existem cabeçalhos na biblioteca padrão C.
Fredoverflow

@FredOverflow Você pode especificar o conjunto de nomes nos quais a transformação deve funcionar. No momento, sua pergunta está formulada de uma maneira que pode levar as pessoas a supor que esse tipo de entrada deve funcionar corretamente.
FUZxxl

@FUZxxl Atualizei a pergunta em conformidade.
Fredoverflow



4

GNU sed -r, 14

sed realmente não tem nenhum conceito de funções, então aqui está um programa completo de sed:

s/(.*)../c\1/

Saída

$ sed -r 's/(.*)../c\1/' <<< stdio.h
cstdio
$ 

O -ritem foi incluído na partitura como um caractere extra.


Esta solução é inválida: provavelmente deveria ser s/\(.*\)\.h/c\1/.
FUZxxl

@FUZxxl - Estou assumindo que -ré passado para o sed. Conforme o código de golfe habitual, preciso contar isso como um ponto extra.
Digital Trauma

@DigitalTraume Observe que -rnão é uma opção padrão e não está disponível fora do GNU sed. Você pode alterar o nome do idioma para GNU sed para refletir isso.
FUZxxl

@FUZxxl Yes. Feito.
Digital Trauma

2
\.hpode ser encurtado para..
Steven Taschuk

3

Prelúdio , 31 caracteres

Como os envios completos de programas são aparentemente aceitáveis, eis um programa que lê o cabeçalho no estilo C do STDIN e imprime o cabeçalho no estilo C ++ no STDOUT:

99+9+(?)###(#
9(1-)       ^)(!)

Isso requer um intérprete compatível com o padrão, que imprime a saída como códigos de caracteres. Se você estiver usando o interpretador Python, precisará definir NUMERIC_OUTPUT = False.

Também exige que não haja nenhuma nova linha no STDIN.

Explicação

No Prelude, todas as linhas são executadas em paralelo, uma coluna por vez. Cada linha tem sua própria pilha, inicializada com uma quantidade infinita de 0s.

99+9+
9(1-)

Este é o mais curto que eu pude para colocar um 99na pilha superior (o código de caractere de c). Primeiro, adiciono 18a pilha superior e empurro a 9para a pilha inferior. A parte inferior é contada 0em um loop, enquanto a pilha superior adiciona mais 9s up. Isso se acumula 99na pilha superior e a pilha inferior é deixada com 0s novamente. Observe que tudo +9+faz parte do loop, portanto, na verdade, existem duas operações de adição por iteração, mas isso não é um problema, graças ao suprimento infinito de 0s abaixo.

Agora (?)lê STDIN, um caractere de cada vez e empurra para a pilha superior. O loop termina no final da entrada, quando o valor ?é zero. ###se livrar desse zero, oe ho .. Agora, o próximo loop exibe números da pilha superior enquanto os copia para a pilha inferior. Isso basicamente reverte a pilha. Observe que os parênteses de abertura e fechamento estão em linhas diferentes - isso não é um problema, porque a posição vertical do )é irrelevante no Prelude, mas economiza um byte na primeira linha.

Por fim, (!)imprime todos os caracteres até que a pilha esteja vazia.


3

Pitão, 7 caracteres

L+\cPPb

Explicação:

L         def y(b):return
 +\c                      "c" +
    PPb                         b[:-1][:-1]

Tente o seguinte:

L+\cPPb
y"stdio.h

no Pyth Compiler / Executor online


Se programas completos fossem permitidos:

Pitão, 6 caracteres

+\cPPQ

Eu nunca vi Pyth. Você seria tão gentil e explicaria o código? :)
fredoverflow 12/02


Eu acredito que você pode usar PPbem vez de<b_2
FryAmTheEggman

@FryAmTheEggman Thanks.
Isaacg

Parece que programas completos são permitidos, para que possa obter a 6.
FryAmTheEggman

3

C ++ 14, 41 caracteres

[](auto&s){s="c"+s.substr(0,s.size()-2);}

Inspirado por essa outra resposta. Fiz uma resposta separada, porque aqui uso um recurso novo no c ++ 14, lambda genérico .

Veja em ação aqui .


2

T-SQL - 58 caracteres

CREATE PROC Q(@ VARCHAR(MAX))AS
SELECT'c'+LEFT(@,LEN(@)-2)

Execute como EXEC Q (sua string aqui)


2

Perl - 20 caracteres

sub{c.pop=~s/..$//r}

Observe como cé uma palavra de barra e, como tal, requer uma falta de use strict. Isso deve ser usado como uma expressão, não como uma declaração.


2

Marbelous, 24

@063
-Z//
3W<C+Z
]]!!
@0

Leva a entrada através de STDIN, sai para STDOUT.

Isso funciona verificando cada byte com .( 0x46). Como 0x46não cabe em um único dígito de base 36, subtraímos 35 ( Z) antes da comparação e o adicionamos novamente antes da saída.

Cada mármore é duplicado por 3W( duplicador de três vias, mas o lado esquerdo é descartado do lado do tabuleiro). O mármore enviado para baixo busca o próximo byte de STDIN. O mármore à direita é marcado para ., então, enviado ou enviado para !!, que finaliza o programa.

O programa começa passando c( 0x63), que será enviado para STDOUT.

Experimente online aqui. As bibliotecas devem estar ativadas, as placas cilíndricas devem estar desativadas.


2

C, 64

Um pouco menor que a referência c:

f(char*h){char*d=strstr(h,".");memmove(h+1,h,d++-h);*d=0;*h=99;}

Provavelmente mais golfe a ser feito com isso.


C, 48 (libc hack)

f(char*h){strcpy(h+1,h);*strstr(h,".")=0;*h=99;}

A página de strcpymanual declara explicitamente "As cadeias não podem se sobrepor". No entanto, descobri que a libc que estou usando parece ser codificada com segurança para lidar com isso corretamente da mesma forma. Esta é a Biblioteca GNU C (Ubuntu EGLIBC 2.19-0ubuntu6.4) no Ubuntu 14.04.


A omissão do tipo de retorno de uma função é legal no C89?
Fredoverflow 12/02/2015

1
@FredOverflow. Sim - o gcc compila isso perfeitamente -std=c89. codegolf.stackexchange.com/a/2204/11259
Digital Trauma

@FredOverflow Sim. O tipo de retorno é padronizado como int.
FUZxxl

A página de manual apenas reitera o padrão - compilar isso com o VC ++ (VS2012) fornece "cstdii" para "stdio.h". Não checou ICC / Sun / clang, mas sua versão de 64 caracteres diz "por quê?" - é quase tão curto quanto ele pode (legalmente) estar em C.
Frasnian

2

JavaScript (ES6) 20

Não acredito que o ES6 ainda estava faltando

s=>'c'+s.slice(0,-2)


2

mk, 34 caracteres

mk (1) é o substituto do plano 9 para o make. Apenas por diversão, esse mkfile converte nomes de cabeçalho C em nomes de cabeçalho C ++:

c%:Q:
    :

%.h:Q: c%
    echo $prereq

Há uma única guia antes :e echo. Use assim:

% mk stdio.h
cstdio



1

R, 33

function(x)sub("(.+)..","c\\1",x)

Esta função usa expressões regulares.

Exemplo de uso:

> (function(x)sub("(.+)..","c\\1",x))("stdio.h")
[1] "cstdio"
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.