2012-04-03 2 views
-1

가능한 중복 : 나는 C에서 다른 문자에 문자열의 문자를 변경하려고 해요 그래서
Problem with processing individual strings stored in an array of pointers to multiple strings in CC 프로그래밍 - 문자열 배열 요소의 변경 문자

확인 문제는 각 문자열이 1D 배열의 요소이므로 문자열 자체가 문자 배열이기 때문에 본질적으로 모두 함께 2D 배열입니다. 어쨌든이 작업을 수행하는 코드를 만드는 데 문제가 있습니다. 이것을 할 수 있습니까? 어떤 도움을 주셔서 감사합니다.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main() 
{ 
int i, size; 
char **a; 

a=(char**)malloc(sizeof(char*)); 

printf("Enter the size of the array:"); 
scanf("%d", &size); 

for(i=0;i<size;i++){ 
a[i]=(char*)malloc(sizeof(char)*8); 
} 

a[3]="Read"; 


while(*(a[3])!='\0'){ 
if(*(a[3]) == 'e'){ 
    *(a[3]) = 'r'; 
} 
} 

printf("%s\n", a[3]); 

system("pause"); 
return 0; 

} 
+0

문제가 정확히 무엇을 걸을를 사용하는 것입니다? 너는 말하지 않았다. 오류가 있습니까? –

답변

0

당신은 a에 충분한 공간을 할당하지 않았다 :

여기에 코드입니다. 대신

a=(char**)malloc(sizeof(char*)); 

당신은

a=(char**)malloc(sizeof(char*)*size); 

이 필요하고 분명이 size을 읽은 후에로 이동해야합니다.

당신이 근본적인 문제 분류가 아니라 일상적인 문제가 여기되면 :

a[3]="Read"; 

이 수정 될 수없는 리터럴에 포인터 a[3] 점을합니다. 대신 리터럴의 내용을 a[3]으로 복사해야합니다. 이처럼 :

strcpy(a[3], "Read"); 

당신은 a[3]=... 그냥 포인터 a[3]를 할당하고 문자열하는 a[3] 점을 수정하지 않는 것을 이해해야합니다. size 다음 a[3] 범위를 벗어 것이다 이후 4보다 작은 경우

는 지금, 당신의 코드는 분명 오류가있을 것입니다,하지만 난 당신이 디버깅 동안 a[3] 단지 일시적인 것 같다.

while 루프가 잘못되었습니다. 당신이 뭔가를 원하는 의견에서 심사 :

char *p = a[3]; 
while (*p != '\0') 
{ 
    if (*p == 'e') 
     *p = 'r'; 
    p++; 
} 

C에서 malloc의 반환 값을 캐스팅, 그래서 캐스트를 제거 할 필요가 없습니다. sizeof(char)은 항상 1과 동일하므로 제거 할 수도 있습니다.

+0

그래, 배열과 요소에 충분한 메모리 공간을 할당하지 않았지만 또 다른 문제가 있습니다. 내가 말한 문자열의 문자를 대체하는 방법을 모른다 [3], 그 이유는 작동하지 않는 while 루프를 사용했기 때문입니다. – user1311135

+0

반대로, 리터럴을 변경할 수는 없지만 실제로는 포인터를 사용할 수 있습니다. 읽기 전용 메모리가 아닌 것 같습니다. –

+0

작동하지 않는 것이 좋지 않습니다. 그것이 당신이 제공하는 모든 정보라면 우리는 어떻게 도울 수 있습니까? 즉, 나는 당신의 문자열 할당이 잘못되었다는 것을 내 대답에서 지적했다. 대신 strcpy를 사용하십시오. –

0

이 :

a=(char**)malloc(sizeof(char*)); 

는 하나의 문자열을위한 공간을 할당합니다. 이 점을 수행 할 수 있습니다 예를 들어, a의 요소, 역 참조, a[3]에서

char **a = NULL; 
size_t number_of_strings = 8; /* for argument's sake */ 

a = malloc(number_of_strings * sizeof(char*)); 
if (!a) 
    return NOT_ENOUGH_MEMORY_ERROR; 

: 당신이 아마 의도하는 것은 같은입니다.당신은 여전히 ​​너무 그 사람들을위한 공간을 할당 할 수 있습니다 : 그와

char *staticStr = "Read"; 
a[3] = malloc(strlen(staticStr) + 1); 
strncpy (a[3], staticStr, strlen(staticStr) + 1); 

시작하고 메모리를 할당하고 방법을 다시 생각하는 것은 당신이 당신의 다른 버그를 해결하는 데 도움이되는지 확인합니다.

일부 노트 :

  • 당신은 항상 당신이해야 1
  • 입니다 메모리를 할당 sizeof(char)를 사용할 필요가 없습니다 당신은 C
  • malloc의 결과를 캐스팅 할 필요가 없습니다 해당 각 a[i]위한 free()a 및 자체 메모리를 방지하는 I가 anoth 참조
0

누수를 사용 어 문제, 당신은 메모리를 할당 할 때 :

a = (char **) malloc(sizeof(char *)); 

당신은 단지 하나의 위치에 대한 메모리를 할당되지만,이 size 위치를 사용하고 있습니다. 그런 다음 코드는 다음과 같아야합니다.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main() 
{ 
int i, size; 
char **a; 
char *ptr; 



printf("Enter the size of the array:"); 
scanf("%d", &size); 

a=(char**)malloc(size * sizeof(char*)); 

for(i=0;i<size;i++){ 
a[i]=(char*)malloc(sizeof(char)*8); 
} 

strcpy(a[3], "Read"); 

ptr=a[3]; 
while(*ptr!='\0'){ 
if(*ptr == 'e'){ 
    *ptr = 'r'; 
} 
ptr++; 
} 

printf("%s\n", a[3]); 

system("pause"); 
return 0; 

} 

물론 할당 된 메모리를 확보해야합니다.

'e'를 'r'로 변경하려고하면 항상 동일한 문자를 가리 킵니다. 배열을 던질 때 새로운 포인터가 필요합니다.

1
a=(char**)malloc(sizeof(char*)); 

printf("Enter the size of the array:"); 
scanf("%d", &size); 

for(i=0;i<size;i++){ 
a[i]=(char*)malloc(sizeof(char)*8); 
} 

아니요. 1 char*을 할당했습니다. 그렇다면 당신은 그것을 size 요소처럼 다루어야합니다. size * sizeof(char*) 바이트를 할당해야합니다. 이 곱셈 또한 오버플로 될 수 있습니다.

a[3]="Read"; 

나쁜 시간. 문자 리터럴의 위치가 "Read"a[3] (이전에는 8 개의 문자 할당을 가리켰다)을 덮어 쓰려고합니다. 이로 인해 이전 할당이 누출되고 수정 불가능한 문자열이 a[3]에 저장됩니다. 너는 strncpy 그 외를보아야한다. 이것 때문에.

0

while 루프는 아무 것도하지 않습니다.

while(*(a[3])!='\0'){ 
if(*(a[3]) == 'e'){ 
    *(a[3]) = 'r'; 
} 
} 

포인터를 앞으로 내리지 않고 첫 번째 위치로 유지합니다.

더 적절한 틱 방법은 임시 포인터를 만들고 문자열

char *temp = a[3]; 
while (*temp != '\0') { 
    if (*temp == 'e') *temp = 'r'; 
    temp++; 
} 
+0

나는 그걸 잘 다루는 다른 사람들이 있다고 생각했다. 물론 리터럴을 수정할 수 있기 때문에 중요하지 않습니다. 디버깅 모드에서는 할 수 없지만 그렇게 할 수는 없습니다. –

+0

@DavidHeffernan "char * a; a ="Hello! "; char * b = a; b [2] = 'b';" 디버그 모드에서 오류가 발생하여 잘 돌아 갔고 릴리스 때까지 수정되었습니다. 증거는 편집 중입니다. –

+0

@DavidHeffernan과 나는 또 다른 StackOverflow 주석을 인용했다. "원래 C89 (C90) 표준은 표준 이전에 너무 많은 코드가 작성 되었기 때문에 리터럴 수정을 금지하지 않았습니다. 컴파일러는 경고를 생성 할 수 있습니다. GCC 3.x가 가지고있는 -fwritable-strings 옵션을 가지고 있지 않지만 GCC 3.x는 적어도 문자열을 수정하려고 시도 할 때 경고 할 것입니다. const에 올바른 코드를 쓰는 것은 const에주의를 기울이지 않는 코드를 작성하는 것보다 어렵습니다. 사람들은 여전히 ​​게으른 길을 택하기 쉽다. "역 호환성을위한 표준은 이것을 허용한다. –