with strings concatenate concatenar and c string char c89 concat

strings - ¿Transmitir char a char array o char array a char?



int to string c (8)

Entonces digamos que tengo un char y quiero strcat () en una matriz char en una sola línea de código. Para [un ejemplo no práctico]:

strcat("ljsdflusdfg",getchar());

O si quisiera hacer lo contrario, ¿cuál sería la función apropiada para concaturar o encasillar cadenas, independientemente del tipo de datos? O tal vez hay alguna sintaxis que me falta ...

Aquí hay un ejemplo. Compila muy bien pero se cuelga.

char* input(){ char* inp=""; while(1){ char c=getchar(); if(c){ if(c==''/n''||c==EOF){ break; }else{ strcat(inp,(char*)c); } } } return inp; }


¿Transmitir char a char array?
Es como decir que quieres lanzar un char en una cuerda.
Simplemente no puedes hacer eso directamente.
En lugar de char, colóquelo en una matriz (myChar []).
Después de eso, hazlo con tu matriz de caracteres original.


El código se bloquea porque strcat espera cadenas terminadas en nulo para sus dos parámetros.

Si desea concatenar un carácter, primero debe crear una cadena terminada en nulo.

char c[2] = {0,0}; c[0] = getchar(); strcat(inp, c);

Pero no use strcat , a menos que pueda garantizar que la cadena de entrada haya asignado espacio para ese carácter adicional. Mejor para ti strncat que también incluye un parámetro para la cantidad de espacio en el primer parámetro (el dest).

Recomiendo leer esto primero.


En primer lugar, está devolviendo un puntero a una matriz asignada de pila. Esto es un comportamiento indefinido. En segundo lugar, está intentando escribir caracteres en la memoria no asignada. En tercer lugar, el tipo de inp es const char* not char* .

Quieres algo como:

char* input(char *dest) { strcpy(dest,""); while(1){ char c=getchar(); if(c){ if(c==''/n''||c==EOF){ break; }else{ strcat(inp,&c); } } } return dest; }


Esto no funcionará porque el puntero * inp char no tiene ninguna memoria que lo respalde. Cuando declara que es char * inp = "" ;, solo le da la dirección de una cadena vacía. Si hubiera dado la siguiente declaración char * inp = "abcdefg", entonces podría haber escrito 7 caracteres antes de sobreescribir el ''/ 0'' y meterse en problemas.

Necesitará aumentar dinámicamente el tamaño de la memoria de respaldo a medida que ingresa más y más caracteres. También tendrá el problema de saber cuándo liberar la memoria para no tener pérdidas de memoria.

Además, su strcat necesita tener ''&'' antes de la c.


Si desea concatenar un solo char en una cadena, puede usar strncat() y especificar el número de caracteres para concatenar como 1 . Pero ten en cuenta que:

  • El buffer de destino debe tener suficiente espacio; y
  • En C89, debe tener un objeto char real para tomar la dirección de (por lo que no puede concatenar directamente el resultado de getchar() .

Por ejemplo:

char str[5] = "foo"; char c; int ch; if ((ch = getchar()) != EOF) { c = ch; strncat(str, &c, 1); }

En C99, puede usar un literal compuesto y la segunda restricción no se aplica:

char str[5] = "foo"; int ch; if ((ch = getchar()) != EOF) { strncat(str, &(char){ ch }, 1); }


strcat trata su argumento como un puntero a una cadena terminada en nulo. Lanzar un char a un char * es simplemente peligroso, y no puedo imaginar ninguna razón por la que alguna vez sea útil (no implica que seas estúpido por intentarlo; todos cometen errores tontos cuando aprenden. Es por eso que estamos aquí). )

La razón es que interpretaría el char byte único, más el sizeof(char*) - sizeof(char) extra sizeof(char*) - sizeof(char) (normalmente 3) bytes que rodean ese char , como un puntero, que apuntaría a ... en cualquier lugar. No tiene forma de saber dónde apunta, ya que 3 de esos bytes están fuera de su control, y por lo tanto, no hay manera de saber si apunta a datos válidos.

Puede tomar esto como un segundo enfoque:

strcat(inp, &c);

Esta vez, estarás mejor, ya que &c es una expresión de tipo char * y no se requieren moldes. Pero de nuevo, strcat supone que su argumento es una cadena terminada en nulo, y como no hay forma de garantizar un byte nulo después de los datos de su char , esto no funcionará.

La mejor manera es esta:

size_t len = strlen(inp); // this may already be calculated somewhere else ... inp[len++] = c; // add c as the last character, and adjust our len inp[len] = ''/0''; // add a new nul terminator to our string

ACTUALIZAR:

En realidad, mentí. La mejor manera es usar los fgets función de biblioteca estándar, que parece estar haciendo más o menos lo que estás tratando de hacer. A decir verdad, lo olvidé, pero si se trata de una tarea para la tarea, es posible que su profesor no quiera que use los datos para que pueda aprender a hacerlo manualmente. Sin embargo, si esto no es tarea, fgets hace exactamente lo que estás buscando. (En realidad, el tercer enfoque está en camino de fgets fgets funciones tipo fgets o fgets ).

También agregaría algunos otros comentarios sobre su función de input :

  1. char* inp = ""; apuntará a datos de solo lectura. Un error en el estándar C (para la compatibilidad con versiones anteriores) permite que los literales de cadena se asignen a los tipos char* lugar de los tipos const char * como debería ser (en mi humilde opinión).

    Hay varias formas de abordar esto, pero lo mejor es la asignación dinámica. Utilice la función malloc para reservar algunos datos, realizar un seguimiento de cuánto ha utilizado en su función y utilizar la función realloc si necesita más espacio para almacenarla. Si necesita ayuda con eso, estoy seguro de que volverá aquí (con suerte, no demasiado pronto) con otra pregunta. :)
  2. getchar() devuelve un int , porque EOF se define como fuera del rango normal de un char . Para distinguir entre cualquier char y EOF , es mejor hacer c an int . De lo contrario, un personaje perfectamente válido puede señalar EOF . Sin embargo, asegúrese de convertir c en una char cuando lo agregue a la cadena.

strcat(inp,(char*)c);

Eso es tratar de concaturar el contenido de la memoria dondequiera que sea ''c'' (como una ubicación de memoria) hasta que encuentre un cero.

Una mejor manera es crear una cadena vacía de cualquier tamaño máximo que creas que sea razonable, llenarlo con ceros y luego simplemente insertar ''c'' en la última posición actual


Una forma simple es usar snprintf:

char newString[50+1]; snprintf(newString, sizeof(newString), "%s%c", "ljsdflusdfg", getchar());

Es una solución simple, pero requiere que sepa aproximadamente qué tan grande va a ser la cuerda antes de tiempo.

Notas: Uso el +1 para recordarme a mí mismo que es necesario que haya espacio para la terminación nula, y snprintf es mejor que sprintf dado que tiene el tamaño del buffer para evitar el desbordamiento del buffer.