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 degetchar()
.
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
:
-
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 tiposchar*
lugar de los tiposconst 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ónmalloc
para reservar algunos datos, realizar un seguimiento de cuánto ha utilizado en su función y utilizar la funciónrealloc
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. :) -
getchar()
devuelve unint
, porqueEOF
se define como fuera del rango normal de unchar
. Para distinguir entre cualquierchar
yEOF
, es mejor hacerc
anint
. De lo contrario, un personaje perfectamente válido puede señalarEOF
. Sin embargo, asegúrese de convertirc
en unachar
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.