variable usar resueltos leer funciones ejercicios ejemplos como caracteres cadenas cadena arreglo c string debugging

usar - ¿Es posible modificar una cadena de caracteres en C?



leer cadena de caracteres en c (9)

He estado luchando durante algunas horas con todo tipo de tutoriales en C y libros relacionados con punteros, pero lo que realmente quiero saber es si es posible cambiar un puntero de char una vez que se ha creado.

Esto es lo que he intentado:

char *a = "This is a string"; char *b = "new string"; a[2] = b[1]; // Causes a segment fault *b[2] = b[1]; // This almost seems like it would work but the compiler throws an error.

Entonces, ¿hay alguna manera de cambiar los valores dentro de las cadenas en lugar de las direcciones del puntero?

Gracias

EDITAR:

Gracias a todos por sus respuestas. Tiene más sentido ahora. Tiene sentido especialmente por qué a veces funcionaba bien y otras veces no funcionaba. Porque a veces pasaba un puntero de char y otras veces una matriz de caracteres (la matriz de caracteres funcionaba bien).


Cuando escribe una "cadena" en su código fuente, se escribe directamente en el ejecutable porque ese valor debe conocerse en tiempo de compilación (hay herramientas disponibles para separar el software y encontrar todas las cadenas de texto sin formato en ellas). Cuando escribe char *a = "This is a string" , la ubicación de "Esto es una cadena" está en el ejecutable, y la ubicación a apunta, está en el ejecutable. Los datos en la imagen ejecutable son de solo lectura.

Lo que debe hacer (como lo han señalado las otras respuestas) es crear esa memoria en una ubicación que no sea de solo lectura: en el montón o en el marco de la pila. Si declara una matriz local, se crea espacio en la pila para cada elemento de esa matriz, y la cadena literal (que se almacena en el ejecutable) se copia a ese espacio en la pila.

char a[] = "This is a string";

también puede copiar esos datos manualmente asignando algo de memoria en el montón, y luego usando strcpy() para copiar un literal de cadena en ese espacio.

char *a = malloc(256); strcpy(a, "This is a string");

Siempre que asigne espacio utilizando malloc() recuerde llamar a free() cuando haya terminado con él (léase: pérdida de memoria).

Básicamente, debe hacer un seguimiento de dónde están sus datos. Cada vez que escriba una cadena en su fuente, esa cadena es de solo lectura (de lo contrario, podría cambiar el comportamiento del ejecutable; imagínese si escribió char *a = "hello"; y luego cambió a[0] a ''c'' . Luego, en otro lugar escribió printf("hello"); Si se le permitiera cambiar el primer carácter de "hello" , y su compilador solo lo almacenara una vez (debería), printf("hello"); cello !)


Debe copiar la cadena en otro buffer de memoria no de solo lectura y modificarlo allí. Utilice strncpy () para copiar la cadena, strlen () para detectar la longitud de la cadena, malloc () y free () para asignar dinámicamente un buffer para la nueva cadena.

Por ejemplo (C ++ como pseudocódigo):

int stringLength = strlen( sourceString ); char* newBuffer = malloc( stringLength + 1 ); // you should check if newBuffer is 0 here to test for memory allocaton failure - omitted strncpy( newBuffer, sourceString, stringLength ); newBuffer[stringLength] = 0; // you can now modify the contents of newBuffer freely free( newBuffer ); newBuffer = 0;


La memoria para a & b no es asignada por usted. El compilador puede elegir libremente una ubicación de memoria de solo lectura para almacenar los caracteres. Por lo tanto, si intenta cambiarlo, puede provocar un error seg. Así que te sugiero que crees una matriz de personajes tú mismo. Algo como: char a[10]; strcpy(a, "Hello"); char a[10]; strcpy(a, "Hello");


Mucha gente se confunde con la diferencia entre char * y char [] junto con literales de cadena en C. Cuando escribes:

char *foo = "hello world";

... en realidad estás apuntando a un bloque constante de memoria (de hecho, lo que el compilador hace con "hello world" en este caso depende de la implementación).

Usar char [] en su lugar le dice al compilador que desea crear una matriz y llenarla con los contenidos, "hello world". foo es el puntero al primer índice de la matriz de caracteres. Ambos son punteros de char, pero solo char [] señalará un bloque de memoria asignado localmente y mutable.


No, no puede modificarlo, ya que la cadena se puede almacenar en la memoria de solo lectura. Si desea modificarlo, puede usar una matriz, por ejemplo,

char a[] = "This is a string";

O alternativamente, puede asignar memoria utilizando malloc, por ejemplo

char *a = malloc(100); strcpy(a, "This is a string"); free(a); // deallocate memory once you''ve done


Parece que tu pregunta ha sido respondida, pero ahora te preguntarás por qué char * a = "String" está almacenada en la memoria de solo lectura. Bueno, en realidad no está definido por el estándar c99, pero la mayoría de los compiladores lo eligen de esta manera para instancias como:

printf("Hello, World/n");

c99 estándar (pdf) [página 130, sección 6.7.8]:

La declaracion:

char s[] = "abc", t[3] = "abc";

define objetos de matriz char "simples" s y t cuyos elementos se inicializan con literales de cadena de caracteres. Esta declaración es idéntica a char

s[] = { ''a'', ''b'', ''c'', ''/0'' }, t[] = { ''a'', ''b'', ''c'' };

El contenido de las matrices es modificable. Por otro lado, la declaración

char *p = "abc";

define p con el tipo "puntero a char" y lo inicializa para apuntar a un objeto con el tipo "array of char" con longitud 4 cuyos elementos se inicializan con un literal de cadena de caracteres. Si se intenta utilizar p para modificar el contenido de la matriz, el comportamiento no está definido.


También strdup usar strdup :

The strdup() function returns a pointer to a new string which is a duplicate of the string s. Memory for the new string is obtained with malloc(3), and can be freed with free(3).

Para tu ejemplo:

char *a = strdup("");


Todas son buenas respuestas que explican por qué no se pueden modificar los literales de cadena porque están ubicados en la memoria de solo lectura. Sin embargo, cuando se trata de empujar, hay una manera de hacer esto. Mira este ejemplo:

#include <sys/mman.h> #include <unistd.h> #include <stddef.h> #include <string.h> #include <stdlib.h> #include <stdio.h> int take_me_back_to_DOS_times(const void *ptr, size_t len); int main() { const *data = "Bender is always sober."; printf("Before: %s/n", data); if (take_me_back_to_DOS_times(data, sizeof(data)) != 0) perror("Time machine appears to be broken!"); memcpy((char *)data + 17, "drunk!", 6); printf("After: %s/n", data); return 0; } int take_me_back_to_DOS_times(const void *ptr, size_t len) { int pagesize; unsigned long long pg_off; void *page; pagesize = sysconf(_SC_PAGE_SIZE); if (pagesize < 0) return -1; pg_off = (unsigned long long)ptr % (unsigned long long)pagesize; page = ((char *)ptr - pg_off); if (mprotect(page, len + pg_off, PROT_READ | PROT_WRITE | PROT_EXEC) == -1) return -1; return 0; }

He escrito esto como parte de mis pensamientos más profundos sobre la corrección de const , que puede encontrar interesante (espero :)).

Espero eso ayude. ¡Buena suerte!


char *a = ""; char *b = "new string, it''s real"; int d = strlen(a); b = malloc(d * sizeof(char)); b = strcpy(b,a); printf("%s %s/n", a, b);