Chapter 11 Strings
문자열 연속된 문자로 한 단위로 취급 크기가 다를 수 있다 고정길이 가변길이 고정길이 : 길이가 정해짐 가변길이 길이조정 문자열 구분자를 사용한 문자열
Figure 11-2
C언어의 문자열 문자열의 크기가 가변적일 때 문자의 끝을 알려주기 위해 구분자를 사용한다. 구분자로 ‘\0’을 사용한다. 문자열 정수는 쌍따옴표(“,”)를 활용하여 표시한다. “Hello”, “I love all of you!” “Hello”는 ‘H’, ‘e’, ‘l’, ‘l’, ‘o’, ‘\0’의 순서로 저장된다. 마지막에 ‘\0’이 들어가므로, 기억될 때 문자열 크기보다 1바이트 더 커지며, 이 한 바이트는 구분자를 위해 사용된다.
Figure 11-3
Figure 11-4
Figure 11-5
Figure 11-6
Figure 11-7
Figure 11-8
변수로 사용되는 문자열 C언어에서는 string(문자열)을 형으로 보지 않고, 문자배열을 이용하여 저장과 복사를 한다. 문자열 최대 크기보다 1 크게 배열을 잡거나 또는 메모리를 배정받아 사용한다. char str[11] 초기화 char str[11] = “Good Day”; char month[] = “January”; char *pStr = “Good Day!”; char str[10] = [‘G’, ‘o’, ‘o’, ‘ ’, ‘D’, ‘a’, ‘y’, ‘!’, ‘\0’]; 조심: 배열이름은 주소상수임!!! char str1[11] = “Hello”; char str2[11]; srt2 = str1; /* ERROR!!!!!!!*/ 문자열의 이름은 배열과 같이 첫 번째 문자를 가리키는 포인터 상수다.
Figure 11-10
문자열 입출력 함수 문자열 입력 %s : scanf에서 사용하며, 앞의 모든 공백은 무시하고, 다시 공백이 나올 때까지 읽고, 공백이 나오면 끝에 NULL을 넣음 scanf(“%s”, month) char month[10]; scanf(“%9s”, month); 편집세트의 이용 앞에 있는 공백을 무시하지 않는다. scanf(“%10[0123456789.,-$]”, str); // 지정된 것만 읽음 scanf(“%81[^\n]”, line); // 81자까지 읽으며, 개행문자가 나오면 읽기를 멈춤
줄의 일부만 읽기 #include <stdio.h> int main (void) { /* Local Definitions */ int amount; /* Statements */ printf("Enter <integer> <integer> <float>: "); while (fscanf(stdin, "%*d%d%*[^\n]", &amount) != EOF) // ‘%*’ 부분은 무시한다. 정수는 두 개가 되어야 작동, 뒷 부분은 상관 없음. printf("Second integer: %d\n", amount); } /* while */ printf("\nThank you\n"); return 0; } /* main */ Results: Enter <integer> <integer> <float>: 123 456 7.89 Second integer: 456 Enter <integer> <integer> <float>: 987 654 3.21 Second integer: 654 Enter <integer> <integer> <float>: ^d Thank you
한 줄에서 앞 부분 공백 없애기 /* Delete leading spaces at beginning of line. Written by: Date: */ #include <stdio.h> #include <ctype.h> int main (void) { /* Local Definitions */ char line[80]; /* Statements */ printf("Enter data: "); while ((*line = fgetc(stdin)) != EOF) if (isspace (*line)) /* Put whitespace back in case only one */ ungetc(*line, stdin); fscanf(stdin, "%*[\t\v\f ]%79[^\n]", line); } /* if */ else fscanf(stdin, "%79[^\n]", line + 1); printf ("You entered: %s\n", line); /* Discard newline and set line to null string*/ fgetc (stdin); *(line + 1) = '\0'; } /* while */ printf("\nThank you\n"); return 0; } /* main */
문자열 출력 printf(“|%30s|\n”, “This is the string”); | This is the string| |12345678901234 |
문자열 입출력 gets와 fgets는 입력스트림의 한 줄을 가져와 스트링으로 넣음. 따라서 마지막에 ‘\0’을 넣어준다. 오류가 생기면 ‘NULL’을 반환한다. char *gets(char *strPtr); 개행문자가 나오면 개행문자를 ‘\0’로 바꾸고 끝냄 char *fgets(char *strPtr, int size, FILE *fp) 줄 넘김, 파일 끝 및 size-1개를 읽었을 때 끝냄
예 include <stdio.h> int main (void) { /* Local Definitions */ char str[81]; /* Statements */ printf("Please enter a string: "); fgets (str, sizeof (str), stdin); printf("Here is your string: \n\t%s", str); return 0; } /* main */ /* Results: Please enter a string: Now is the time for all students Here is your string: Now is the time for all students */
스트링을 줄로 출력 puts와 fputs는 문자열을 한 줄로 출력한다. puts는 ‘\0’을 newline으로 대체하지만, fputs는 ‘\0’을 버린다. 성공하면 정수를 반환하고, 실패하면 EOF를 반환한다. 그러나 문자열 끝에 ‘\0’이 없으면 오류로 보지 않으니 조심할 것!! 형식 int puts(const char *strPtr); int fputs(const char *strPtr, FILE *fp);
예 #include <stdio.h> int main (void) { /* Local Definitions */ char str[] = "Necessity Is the Mother of Invention."; char *pStr = str; /* Statements */ puts(pStr); puts(pStr + 13); return 0; } /* main */ /* Results: Necessity Is the Mother of Invention the Mother of Invention. */
타자기 프로그램 include <stdio.h> #include <stdlib.h> int main (void) { /* Local Definitions */ char str[100]; FILE *fpOut; /* Statements */ if (!(fpOut = fopen ("P11-06.TXT", "w"))) printf("\aCould not open output file.\n"); (100); } /* (if) */ while (fgets(str, sizeof (str), stdin)) fputs(str, fpOut); fclose (fpOut); return 0; } /* main */ /* Results: Now is the time For all good students To come to the aid Of their school.^d P11-06.txt contents: Of their school. */
문자열의 배열 가변길이 배열(ragged array) 실제 응용에서 문자열의 길이가 일정하지 않으므로 가변길이 배열로 문자열을 표현하는 것이 효과적이다.
예 include <stdio.h> int main (void) { /* Local Definitions */ char *pDays[7]; char **pLast; char **pWalker; /* Statements */ pDays[0] = "Sunday"; pDays[1] = "Monday"; pDays[2] = "Tuesday"; pDays[3] = "Wednesday"; pDays[4] = "Thursday"; pDays[5] = "Friday"; pDays[6] = "Saturday"; printf("The days of the week\n"); pLast = pDays + 6; for (pWalker = pDays; pWalker <= pLast; pWalker++) printf("%s\n", *pWalker); return 0; } /* main*/
문자열 조작 함수I strlen: 문자열 길이 strcpy: strncpy: 문자열 길이 복사 strcmp: 문자열 비교 int strlen(const char *string); strcpy: char *strcpy(char *to_string, const char *from_string); 자기 자신의 일부를 자신에게 복사할 때 주의: strcpy((s2+2), s2) 결과예측이 불가능 strncpy: 문자열 길이 복사 char *strcpy(char *to_string, const char *from_string, int size); strcmp: 문자열 비교 int strcmp (const char *string1, const char *string2); 0이면 일치, 양수면 string1이 크고, 음수면 string2가 큼 strncmp: 문자열 길이 비교 int strcmp (const char *string1, const char *string2, int size); strcat: 문자열 연결 char *strcat (char *string1, const char *string2); strncat: 문자열 길이 연결 char *strcat (char *string1, const char *string2, int size);
문자열 조작 함수II strstr, strrstr: 문자열에 문자열이 있는지 char *strstr(const char *string, const char *sub_string) char *strrstr(const char *string, const char *sub_string) 성공하면 문자열의 시작 위치 반환, 아니면 NULL 반환 strspn: 문자열 집합에 없는 문자가 나오면 중단 int strspn(const char *string1, const char *set); 일치하는 문자의 개수를 출력 strcspn: strspn과 반대 int strcspn(const char *string1, const char *set); 일치하는 문자가 문자열에 없으면 문자열 길이를 반환 strpbrk: 문자포인터를 반환 char *strpbrk(const char *string1, const char *set);
문자열 조작함수 III strtok : 토큰 분리 strtol : 문자열을 정수로 strtod : 문자형을 더블형으로 char *strtok (char *string, const char *delimiters); strtol : 문자열을 정수로 long strtol (char *str, char **ptr, int base); strtod : 문자형을 더블형으로 double strtod (char *str, char **ptr);
Figure 11-14
Figure 11-15
Heap 예제 I #include <stdio.h> #include <stdlib.h> #include <string.h> #define FLUSH while (getchar() != '\n') int main (void) { /* Local Definitions */ char input[81]; char **pNames; /* array of pointers to char */ int size; int namesIndex; /* Statements */ printf("How many names do you plan to input? "); scanf ("%d", &size); FLUSH; /* Allocate array in heap. One extra element added for loop control */ pNames = (char **) calloc (size + 1, sizeof (char *)); printf("Enter names. <EOF> to stop\n");
Heap 예제 II while (namesIndex < size && fgets(input, sizeof(input), stdin)) { *(pNames + namesIndex) = (char *) calloc (strlen(input) + 1, sizeof(char)); strcpy (*(pNames + namesIndex), input); namesIndex++; } /* while */ *(pNames + namesIndex) = NULL; printf("\nYour names are: \n"); while (*(pNames + namesIndex)) printf("%3d: %s", namesIndex, *(pNames + namesIndex) ); return 0; } /* main */ Results: How many names do you plan to input? 3 Enter names. <EOF> to stop Tom Rico Your names are: 0: Tom 1: Rico
Figure 11-16
Figure 11-17
Figure 11-18
Figure 11-19
Figure 11-20
Figure 11-21
Figure 11-22
메모리 양식 메모리 문자열 읽기 메모리 문자열 쓰기 int sscanf (char *str, const char *format_string, …) sscanf(strIn, “%25[^;]%*%4s%d%*[^ABCDEF]%c”, name, stuNo, &score, &grade); Eindten, Albert; 1234 67 D 메모리 문자열 쓰기 int sprintf (char *out_string, const char *format_string, ….);
Figure 11-23
Figure 11-24
Figure 11-25
Figure 11-26
Figure 11-27
Figure 11-28
Figure 11-29
11장 실습문제 및 12장 예습 11장 실습 12장 예습 strcpy, strcat를 구현하라!!! 31번, 36번, 44번 13, 14, 19, 20