Pregunta

Digamos que tengo un char * str = " 0123456789 " y quiero cortar la primera y las últimas tres letras e imprimir solo el medio, ¿cuál es la forma más simple y segura? de hacerlo?

Ahora el truco: la parte a cortar y la parte a imprimir son de tamaño variable, así que podría tener una char * muy larga o una muy pequeña.

¿Fue útil?

Solución

Puede usar printf () y una cadena de formato especial:

char *str = "0123456789";
printf("%.6s\n", str + 1);

La precisión en el especificador de conversión % s especifica el número máximo de caracteres para imprimir. También puede utilizar una variable para especificar la precisión en el tiempo de ejecución:

int length = 6;
char *str = "0123456789";    
printf("%.*s\n", length, str + 1);

En este ejemplo, el * se usa para indicar que el siguiente argumento ( length ) contendrá la precisión para la conversión de % s , el argumento correspondiente debe ser un int .

La aritmética del puntero se puede usar para especificar la posición inicial como hice anteriormente.

[EDIT?

Un punto más, si su cadena es más corta que su especificador de precisión, se imprimirán menos caracteres, por ejemplo:

int length = 10;
char *str = "0123456789";
printf("%.*s\n", length, str + 5);

Imprimirá " 56789 " ;. Si siempre desea imprimir un cierto número de caracteres, especifique un ancho de campo mínimo y una precisión:

printf("%10.10s\n", str + 5);

o

printf("%*.*s\n", length, length, str + 5);

que se imprimirá:

"     56789"

Puede usar el signo menos para justificar a la izquierda la salida en el campo:

printf("%-10.10s\n", str + 5);

Finalmente, el ancho de campo mínimo y la precisión pueden ser diferentes, es decir,

printf("%8.5s\n", str);

imprimirá como máximo 5 caracteres justificados a la derecha en un campo de 8 caracteres.

Otros consejos

Robert Gamble y Steve por separado tienen la mayoría de las piezas. Ensamblado en un todo:

void print_substring(const char *str, int skip, int tail)
{
    int len = strlen(str);
    assert(skip >= 0);
    assert(tail >= 0 && tail < len);
    assert(len > skip + tail);
    printf("%.*s", len - skip - tail, str + skip);
}

Invocación para el ejemplo:

print_substring("0123456789", 1, 3);

Si no le importa modificar los datos, podría hacer algo de aritmética de puntero. Esto supone que str es un puntero de caracteres y no una matriz:

char string[] = "0123456789";
char *str = string;

str += 3; // "removes" the first 3 items
str[4] = '\0'; // sets the 5th item to NULL, effectively truncating the string

printf(str); // prints "3456"

Aquí hay una función de subcadena limpia y simple que desenterré de mi biblioteca personal que puede ser útil:

char *
substr(const char *src, size_t start, size_t len)
{
  char *dest = malloc(len+1);
  if (dest) {
    memcpy(dest, src+start, len);
    dest[len] = '\0';
  }
  return dest;
}

Es probable que se explique por sí mismo, pero toma una cadena, una posición inicial (que comienza en cero) y una longitud y devuelve una subcadena de la cadena original o un puntero nulo si malloc falla. El puntero devuelto puede ser free 'd por la persona que llama cuando ya no se necesita memoria. En el espíritu de C, la función no valida la posición inicial y la longitud proporcionadas.

Creo que hay algo de magia que puedes hacer con printf que solo imprimirá un cierto número de caracteres, pero no se entiende ni se usa comúnmente. Intentamos hacerlo en un trabajo anterior y no pudimos hacerlo funcionar de manera consistente.

Lo que haría es guardar un carácter, anular ese carácter en la cadena, imprimirlo y luego guardarlo de nuevo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top