Convertir nombres de encabezado C a nombres de encabezado C ++


27

En la biblioteca estándar de C, los nombres de encabezado terminan con un .hsufijo:

stdio.h

En C ++, esos nombres de encabezado están disponibles en una forma alternativa, con un cprefijo en su lugar:

cstdio

Escribe una función que convierta la primera forma en la segunda. Puede realizar la conversión en el lugar, o dejar la cadena original intacta y devolver una nueva cadena. Cualquier cosa que se sienta natural en su idioma de elección.

El código debe compilarse / interpretarse sin errores. Las advertencias del compilador son aceptables.

Aquí está su solución de línea de base C. Tiene 70 caracteres y genera una advertencia sobre strlen:

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

La solución más corta (medida en número de caracteres) gana.

Actualización: si su idioma de elección no admite funciones, también se aceptan programas completos.

Actualización: según lo sugerido por FUZxxl, aquí hay una lista completa de los archivos de encabezado en la biblioteca estándar de 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

Específicamente, no hay nombres de encabezado con múltiples puntos en ellos.

Respuestas:


37

80386 código máquina, 13 bytes.

Hexdump del código:

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

Código fuente (puede ser compilado por 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
    }
}

Convierte la cadena en su lugar. El código es tan simple que no necesita guardar y restaurar registros (usando solo aly ecx, que la fastcallconvención permite clobber).


Niza, esto me lleva de nuevo :)
fredoverflow

¡Definitivamente una de las soluciones más geniales! Pero el código fuente no es realmente de 13 bytes, solo la forma compilada (que creo que pocos de nosotros querríamos escribir en un editor hexadecimal).
Según Lundberg

3
Dale su victoria. Byte = carácter es una interpretación perfectamente razonable aquí.
Joshua

77
@PerLundberg Veo que el código fuente en este caso es la explicación ampliada / comentada "cómo funciona" que mucha gente incluye en sus idiomas ultracompactos. Para un programa tan pequeño, bien podría haber sido escrito a mano. :)
esponjoso

@fluffy Fair point. Y sí, la cantidad de personas que podrían escribir el código binario de memoria es ciertamente> 0, a pesar de que no conozco a nadie que sea geek. ;)
Según Lundberg


14

CJam, 6 bytes

'clW(<

Este es un programa completo que lee la cadena a través de STDIN

Explicacion :

'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";

Pruébalo en línea aquí


¿No -2es tan bueno como W(?
Esolanging Fruit


11

brainfuck - 25 23 bytes

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

Si su idioma de elección no admite funciones, también se aceptan programas completos.

Este es un programa completo que recibe información de 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

¿No
saldría

@feersum Si su intérprete le permite salir del borde izquierdo, sí. Cada uno que he usado coloca la cinta.
undergroundmonorail

2
@feersum Si desea probarlo pero su intérprete le permite caerse, puede arreglarlo con un >al principio.
undergroundmonorail

10

Haskell - 23 caracteres

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

Haskell - 16 caracteres, como lo sugiere nimi

('c':).init.init

2
Al soltar los últimos 2 caracteres en init.initlugar de llevarlos todos al primero, se .guardan algunos bytes.
nimi

@nimi ¡Esa es una sugerencia increíble!
fredoverflow

10

C, 38

Ver en Ideone

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

ses un puntero a la cadena de entrada y oes donde se debe escribir la salida.

Encontré una manera de abusar snprintf. La cadena de salida es convenientemente un carácter más corto que la entrada, y la longitud máxima de la cadena escrita por snprintf1 es menor que el nargumento, por lo que corta el .h. Nota: esta técnica no funcionará con la implementación de Microsoft porque hace lo incorrecto y no puede anular la cadena.


8

Archivo por lotes de Windows 11

@echo c%~n1

El primer parámetro pasado es% 1. El modificador ~ n devuelve solo el nombre de archivo sin extensión.

Si es aceptable hacer eco del comando expandido en la pantalla también, entonces la @ inicial podría eliminarse.


8

Arquitectura de tipo de nodo TIS T21 - 85 bytes

Esta respuesta es solo por diversión; el lenguaje surgió después de que se escribió este desafío y, por lo tanto, no puedo ganar con él. (No es que fuera a hacerlo).

De acuerdo, me divertí un poco con este. Probablemente debería llamar al lenguaje "TIS-100", pero ¿por qué romper el carácter? :RE

TIS-100 es un juego sobre la programación de una computadora con una arquitectura totalmente única y extraña. Escribí un rompecabezas personalizado para este desafío, que me permite tomar datos y verificar resultados con una "cadena" conocida y correcta. Desafortunadamente, no hay forma de manejar cadenas o caracteres, por lo que este programa simplemente usa el valor ASCII de cada carácter para entrada y salida.

Si desea verlo en acción, puede usar este emulador , o simplemente verme ejecutarlo en el juego real aquí . Tenga en cuenta que en el video, la línea final del primer nodo es D:MOV UP NIL. Después de terminar el video, me di cuenta de que podía jugar golf D:ADD UP. Funcionalmente no hay diferencia, porque el valor de ACC se sobrescribe inmediatamente de todos modos.

Esta es la cadena que utilicé para mi recuento 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

Ese es el texto de cada nodo no vacío, separado por líneas nuevas (agregando efectivamente 1 byte por cada nodo usado más allá del primero, reflejando nuestra regla sobre el código en múltiples archivos).


7

Dyalog APL (8 caracteres)

'c',¯2↓⊢

Esta solución es exactamente la misma que la solución J que presenté pero usa un carácter menos debido a que es un carácter menor que }..


7

J (9 caracteres)

'c',_2}.]
  • |yes la magnitud de y(también llamado valor absoluto)
  • x }. ydeja caer |xobjetos de y; los elementos se dejan caer desde el frente si xes positivo, desde el final si xes negativo.
  • x , yAnexa xy y.
  • 'c' , _2 }. yhace la transformación que quieres; en notación tácita esto se puede expresar como 'c' , _2 }. ].

7

Avestruz 0.6.0 , 8 caracteres

););"c\+

)es el operador de "descompresión correcta". Cuando se aplica a una cadena, se convierte, por ejemplo, `foo`en `fo` `o`. ;se usa para extraer el carácter adicional, y esto se hace nuevamente.

Entonces, "ces empujado. Esto es simplemente una abreviatura de `c`.

\+ intercambia los dos elementos superiores de la pila y los concatena.


¿Este lenguaje fue creado por ti?
Ismael Miguel


Yo creo que sí. Ya lo revisé, por lo tanto, pensé en ello. No hay referencia en ese idioma en ninguna parte. Solo aqui. Entonces, asumí que fue hecho por ti. Para un chico de 14 años, fuiste muy lejos en la programación. +1000 por eso!
Ismael Miguel

@IsmaelMiguel Whoops, lo siento, debería haberte dicho que soy KeyboardFire en Github. ¡Gracias!
Pomo de la puerta

No necesitas hacerlo. Es casi implícito. Soy ismael-miguel (muy original, consulte github.com/ismael-miguel ). No tengo nada interesante y útil allí, pero puedes comprobarlo. Pero estoy interesado en tu idioma. Lo único completo es la clase UIntArray para php ( github.com/ismael-miguel/php-uintarray si está interesado).
Ismael Miguel

7

piet ( 9x11 = 99 8X11 = 88)

v2

otro intento (2x37 = 74)

ingrese la descripción de la imagen aquí

Es difícil hacerlo mucho más pequeño ya que necesita generar un 99 ('c') y un 46 ('.'), Y eso toma espacio en piet.


1
Piet nunca se mide en caracteres, solo en codeles, por lo que no necesita mencionar el bit de 0 caracteres :) También es mucho blanco
Sp3000

tratando de comprimir, pero es un poco difícil. Tengo problemas para que termine si elimino otra fila o columna.
captncraig

Esto es un poco de trampa, pero me gusta. Esto es como usarlo /dev/nullcomo código fuente.
Ismael Miguel

2
De acuerdo con META ( meta.codegolf.stackexchange.com/questions/4782/… ), su programa no está obligado a finalizar. Mientras lo haga, su programa puede ejecutarse para siempre. Lee la primera respuesta a la pregunta.
Ismael Miguel

6

F # - 39 37 31

31 - ¡Porque la diferencia de tipos en rocas 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)

No funciona para un encabezado llamado foo.hoo.h.
FUZxxl

3
@FUZxxl No hay tales encabezados en la biblioteca estándar de C.
fredoverflow

@FredOverflow Es posible que desee especificar el conjunto de nombres en los que debe funcionar la transformación. En este momento, su pregunta está redactada de una manera que podría llevar a las personas a suponer que este tipo de entrada debe funcionar correctamente.
FUZxxl

@FUZxxl He actualizado la pregunta en consecuencia.
fredoverflow



4

GNU sed -r, 14

sed realmente no tiene ningún concepto de funciones, así que aquí hay un programa sed completo:

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

Salida

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

El -rha sido incluido en la partitura como un personaje extra.


Esta solución no es válida: probablemente debería serlo s/\(.*\)\.h/c\1/.
FUZxxl

@FUZxxl - Supongo que -rse pasa a sed. Según el código de golf habitual , necesito contar eso como un punto extra.
Trauma digital

@DigitalTraume Aviso que -rno es una opción estándar y no está disponible fuera de GNU sed. Es posible que desee cambiar el nombre del idioma a GNU sed para reflejar eso.
FUZxxl

@FUZxxl Sí. Hecho.
Trauma digital

2
\.hse puede acortar a..
Steven Taschuk

3

Preludio , 31 caracteres

Dado que las presentaciones completas del programa son aparentemente aceptables, aquí hay un programa que lee el encabezado de estilo C de STDIN e imprime el encabezado de estilo C ++ en STDOUT:

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

Esto requiere un intérprete compatible con el estándar que imprima los resultados como códigos de caracteres. Si está utilizando el intérprete de Python , deberá configurarlo NUMERIC_OUTPUT = False.

También requiere que no haya una nueva línea final en STDIN.

Explicación

En Preludio, todas las líneas se ejecutan en paralelo, una columna a la vez. Cada línea tiene su propia pila, inicializada en una cantidad infinita de 0s.

99+9+
9(1-)

Este es el más corto que se me ocurrió para obtener un 99en la pila superior (el código de carácter de c). Primero sumo 18en la pila superior y empujo a 9en la pila inferior. La parte inferior luego cuenta hacia atrás 0en un bucle, mientras que la pila superior agrega más 9s. Esto se suma a 99la pila superior, y la pila inferior se deja con 0s nuevamente. Tenga en cuenta que todo +9+es parte del ciclo, por lo que en realidad hay dos operaciones de suma por iteración, pero eso no es un problema, gracias al suministro infinito de 0s debajo.

Ahora (?)lee STDIN, un personaje a la vez y empuja a la pila superior. El bucle termina al final de la entrada, cuando ?empuja un cero. ###se deshace de ese cero, el hy el .. Ahora el siguiente ciclo muestra los números de la pila superior mientras los copia en la pila inferior. Esto esencialmente invierte la pila. Tenga en cuenta que los paréntesis de apertura y cierre están en diferentes líneas; esto no es un problema, porque la posición vertical de la )es irrelevante en Preludio, pero me ahorra un byte en la primera línea.

Por último, (!)imprime todos los caracteres hasta que la pila esté vacía.


3

Pyth, 7 caracteres

L+\cPPb

Explicación:

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

Prueba esto:

L+\cPPb
y"stdio.h

en el compilador / ejecutor de Pyth en línea


Si se permitieran programas completos:

Pyth, 6 caracteres

+\cPPQ

Nunca he visto a Pyth. ¿Serías tan amable y explicarías el código? :)
fredoverflow


Creo que puedes usar en PPblugar de<b_2
FryAmTheEggman

@FryAmTheEggman Gracias.
isaacg

Parece que se permiten programas completos, por lo que puede llegar a 6.
FryAmTheEggman

3

C ++ 14, 41 caracteres

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

Inspirado por esta otra respuesta. Hice una respuesta por separado porque aquí uso una función que es nueva en c ++ 14, lambda genérico .

Véalo en acción aquí .


2

T-SQL - 58 caracteres

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

Ejecutar como EXEC Q (su cadena aquí)


2

Perl - 20 caracteres

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

Tenga en cuenta cómo ces una palabra simple y, como tal, esto requiere una falta de use strict. Esto debe usarse como una expresión, no como una declaración.


2

Marbelous, 24

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

Toma entrada a través de STDIN, salidas a STDOUT.

Esto funciona comprobando cada byte con .( 0x46). Como 0x46no puede caber dentro de un solo dígito base-36, restamos 35 ( Z) antes de comparar y lo sumamos nuevamente antes de generar.

Cada canica está duplicada por 3W( duplicador de tres vías, pero el lado izquierdo se descarta del lado del tablero). El mármol enviado hacia abajo recupera el siguiente byte de STDIN. La canica a la derecha se verifica y .luego se envía o se envía a !!, lo que finaliza el programa.

El programa comienza pasando c( 0x63) a través, que se enviará a STDOUT.

Pruébelo en línea aquí. Las bibliotecas deben estar habilitadas, las placas cilíndricas deben estar deshabilitadas.


2

C, 64

Un poco más corto que la referencia c:

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

Probablemente más golf para hacer con esto.


C, 48 (hack de libc)

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

La página de strcpymanual indica explícitamente "Las cadenas no pueden superponerse". Sin embargo, descubrí que la libc que estoy usando parece estar codificada de manera segura para manejar esto correctamente de todos modos. Esta es la Biblioteca GNU C (Ubuntu EGLIBC 2.19-0ubuntu6.4) en Ubuntu 14.04.


¿Es legal omitir el tipo de retorno de una función en C89?
fredoverflow

1
@FredOverflow. Sí, gcc compila esto muy bien con -std=c89. codegolf.stackexchange.com/a/2204/11259
Trauma digital

@FredOverflow Sí. El tipo de retorno predeterminado es int.
FUZxxl

La página de manual simplemente reitera el Estándar: compilar esto con VC ++ (VS2012) da "cstdii" para "stdio.h". No verifiqué ICC / Sun / clang, pero tu versión de 64 caracteres dice "¿por qué?" - es lo más corto posible (legalmente) en C.
frasnian

2

JavaScript (ES6) 20

No puedo creer que ES6 todavía faltara

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


2

mk, 34 caracteres

mk (1) es el reemplazo del Plan 9 para make. Solo por diversión, este archivo mk convierte los nombres de encabezado C en nombres de encabezado C ++:

c%:Q:
    :

%.h:Q: c%
    echo $prereq

Hay una sola pestaña antes :y echo. Usar así:

% mk stdio.h
cstdio



1

R, 33

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

Esta función usa expresiones regulares.

Ejemplo de uso:

> (function(x)sub("(.+)..","c\\1",x))("stdio.h")
[1] "cstdio"
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.