{ }codelper

배우기 › C

데이터 · 12

문자열 만들어 가기

조각을 붙여 문자열 만들기, 사이에 넣어 잇기, 한 줄에 이어 찍기.

출력할 문자열을 한 번에 쓸 수 없을 때는 조각을 하나씩 붙여서 만들어요.
아래 예제는 낱말들을 읽어서 첫 글자만 모은 문자열, 낱말을 쉼표로 이은 문자열, 낱말 길이를 빈칸으로 이은 한 줄을 차례로 찍어요.

#include <stdio.h>#include <string.h> int main(void) {    char words[100][51], initials[101];    int n = 0, lens[100];    while (n < 100 && scanf("%50s", words[n]) == 1) n++;    for (int i = 0; i < n; i++) {        initials[i] = words[i][0]; // 한 조각씩 붙여 가요    }    initials[n] = '\0'; // 문자열의 끝 표시    printf("%s\n", initials);    for (int i = 0; i < n; i++) {        if (i > 0) printf(", "); // 사이에만 ", "        printf("%s", words[i]);    }    printf("\n");    for (int i = 0; i < n; i++) lens[i] = strlen(words[i]);    for (int i = 0; i < n; i++) {        if (i > 0) printf(" "); // 첫 값 앞에는 안 찍어요        printf("%d", lens[i]);    }    printf("\n");    return 0;}
stdin
red green blue
stdout
rgb
red, green, blue
3 5 4

핵심

  • 만들어 가기: 빈 문자열에서 시작해, 반복하면서 조각을 뒤에 붙여요(initials += w[0]).
    합계를 total += x로 모으던 것과 같은 꼴이에요.
  • Java와 C#의 +=는 붙일 때마다 지금까지의 문자열을 통째로 새로 만들어요.
    그래서 조각을 모아 두었다가 끝에 한 번만 문자열로 바꾸는 StringBuilder가 따로 있어요.
  • 수를 붙일 때 저절로 문자열로 바꿔 주는 언어가 있고, 직접 바꿔서 붙여야 하는 언어가 있어요.
  • 잇기(join)는 목록의 값들 사이에만 구분 문자열을 넣어 하나로 만들어요.
    red, green, blue를 ", "로 이으면 red, green, blue예요.
    맨 뒤에는 붙지 않아요.
  • 잇기가 없는 언어에서는 반복문으로 써요.
    첫 값이 아닐 때만 구분 문자열을 먼저 찍고 값을 찍으면, 맨 뒤에 구분 문자열이 남지 않아요.
  • 수 여러 개를 한 줄에 찍는 것도 같은 일이에요.
    한 번에 이어 찍는 짧은 방법이 있는 언어도 있고, 줄을 바꾸지 않는 출력으로 하나씩 찍는 언어도 있어요.

언어별로 쓰는 법

Python붙이기 s += 조각 — 수는 str(n)으로 바꿔서 붙여요.
조각이 많으면 목록에 append하고 끝에 "".join(parts).
잇기 ", ".join(words)는 문자열 목록만 받아요.
한 줄 출력은 print(*nums), 구분을 바꾸려면 print(*nums, sep=", ")
JavaScript붙이기 s += 조각 — 수도 저절로 문자열이 돼요.
잇기 words.join(", ")는 수 배열도 되고, 괄호를 비운 join()은 쉼표로 이어요.
한 줄 출력은 console.log(nums.join(" "))
TypeScriptJavaScript와 같아요
JavaStringBuilder sb = new StringBuilder(); 다음 sb.append(조각) — 글자·수·문자열을 모두 받아요.
끝에 sb.toString()으로 바꾸거나 그대로 println(sb).
잇기 String.join(", ", words)는 문자열만 받아요.
수는 System.out.print로 하나씩 찍거나 StringBuilder에 모아요
C#var sb = new StringBuilder();(using System.Text;) 다음 sb.Append(조각), 끝에 sb.ToString().
잇기 string.Join(", ", words)는 수 배열도 받아서, 한 줄 출력이 Console.WriteLine(string.Join(" ", nums))예요
C++std::string은 고칠 수 있어서 s += 조각이 제자리에서 붙어요.
수는 std::to_string(n)으로 바꿔 붙여요.
잇기가 없어서 if (i > 0) std::cout << ", ";처럼 반복문으로 써요.
std::ostringstream에 <<로 모았다가 .str()로 꺼내도 돼요
C문자열은 char 배열이라, 자리를 넉넉히 잡고 칸마다 글자를 넣은 뒤 끝에 '\0'을 넣어요.
문자열을 붙일 때는 strcat(buf, "cd"), 수는 sprintf(buf + len, "%d", n).
잇기가 없어서 반복문과 printf로 써요
Craykon붙이기 s += 조각 — 수도 저절로 문자열이 돼요.
잇기 words.잇기(", ")는 수 목록도 돼요.
콘솔.쓰기(목록)은 빈칸으로 이어 찍고, 하나씩 찍을 때는 줄을 바꾸지 않는 콘솔.이어쓰기(값)

자주 하는 실수

구분 문자를 값 뒤에 붙였어요

words = ["red", "green", "blue"]
line = ""
for w in words:
    line += w + ","
print(line)

→ red,green,blue, — 맨 뒤에 쉼표가 하나 더 붙어요

잇기를 쓰거나, 첫 값이 아닐 때만 값 앞에 붙여요: if line: line += "," 다음에 line += w.

따옴표 문자열 둘을 +로 붙였어요C · C++

char *s = "ab" + "cd";

→ 컴파일 오류 invalid operands to binary + — C의 문자열은 주소라서 더할 수 없어요. C++에서 std::string s = "ab" + "cd";도 같은 까닭으로 컴파일 오류예요

C는 char buf[10] = "ab"; strcat(buf, "cd");, C++는 한쪽을 std::string으로 만들어요: std::string("ab") + "cd".

수 목록을 그대로 이었어요Python · Java

print(", ".join([1, 2, 3]))

→ Python은 TypeError: sequence item 0: expected str instance, int found. Java도 int[] nums에 String.join(", ", nums)를 쓰면 컴파일 오류예요

Python은 ", ".join(map(str, nums))나 print(*nums, sep=", "), Java는 StringBuilder에 모아요.
JavaScript·C#·크레이콘의 잇기는 수도 받아요.

언어마다 다른 점
조각이 많을 때는 붙이는 방법에 따라 시간이 크게 달라져요.
이 사이트 채점기와 같은 환경에서 한 글자씩 20만 번 붙여 보니 Java는 +=로 1초쯤, StringBuilder로 1~2ms였고, C#은 +=로 2~3초, StringBuilder로 1~2ms였어요.
Python도 예제처럼 함수 밖에서 +=로 붙이면 0.5초쯤, 목록에 모았다가 join하면 10ms가 안 걸렸어요.
JavaScript(Node.js)는 +=로도 10ms 안팎이었어요.
잰 시간은 컴퓨터마다 달라요.
그리고 C++에서 수를 붙일 때는 꼭 std::to_string을 거쳐요.
s += 65는 "65"가 아니라 코드 65인 글자 A를 붙여요.

연습 문제