나는 어떻게 변환하는 문자열로 축약된 형태?
-
06-09-2019 - |
문제
고 싶 핏 문자열로 특정 폭입니다.예를 들어,"Hello world!"->"...세상","안녕하세요...","그는 rld...".
당신이 어디서 찾을 수 있는지 알아에 대한 코드는?그것은 정교한 속임수에 대한 매우 유용한 정보를 나타내는,그리고 나는 그것을 추가하는 내용(물론).
편집:도시에서 가장 유명한 지역인 스테이를 언급하는 글꼴 부분입니다.단지에 대한 폭 고정한 문자열에 따라 글꼴 얼굴입니다.
해결책
그것은 아주 간단한 알고리즘을 직접 작성하는 경우에 당신은 그것을 찾을 수 없습니다 어디서나 의사 코드 같은 것:
if theString.Length > desiredWidth:
theString = theString.Left(desiredWidth-3) + "...";
또는 당신이 원하는 경우 생략에서 문자열의 시작,그 두 번째 줄은 다음과 같습니다:
theString = "..." + theString.Right(desiredWidth-3);
또는 당신이 원하는 경우 그것은 중간에:
theString = theString.Left((desiredWidth-3)/2) + "..." + theString.Right((desiredWidth-3)/2 + ((desiredWidth-3) mod 2))
편집:
겠다고 가정하면 사용 MFC.때문에 당신은 그것을 원하는 글꼴을 사용할 수 있습니다 CDC::GetOutputTextExtent 기능입니다.Try:
CString fullString
CSize size = pDC->GetOutputTextExtent(fullString);
bool isTooWide = size.cx > desiredWidth;
는 경우에는 너무 크고,다음할 수 있습니다 다음 검색을 시도하고 찾아내는 가장 긴 문자열을 맞을 수 있;고 가능할 것으로 예상한 영리한 검색으로 당신이 원한다면-예를 들어,당신은 수도"Hello Worl..."다음"안녕하세요 Wor..."다음"안녕하세요 Wo...";를 제거 하나의 문자를 찾을 때까지 그것은 맞습니다.또는,당신이 할 수 있는 검색 도"Hello Worl..."-작동하지 않는 경우,다음 사용 절반의 원본 텍스트:"안녕하세요..."-는 경우에 맞는,시간 및:"안녕하세요 Wo..."찾을 때까지 가장 긴는 여전히 맞습니다.거나 시도할 수 있습니다 몇 가지 추정을 휴리스틱(나눈 총 길이여 원하는 길이 비례적으로 견적이 필요한 숫자,문자의 검색습니다.
간단한 해결책은 다음과 같습니다.
unsigned int numberOfCharsToUse = fullString.GetLength();
bool isTooWide = true;
CString ellipsis = "...";
while (isTooWide)
{
numberOfCharsToUse--;
CString string = fullString.Left(numberOfCharsToUse) + ellipsis;
CSize size = pDC->GetOutputTextExtent(string);
isTooWide = size.cx > desiredWidth;
}
다른 팁
그것은 정말 아주 사소한;나는 생각하지 않을 찾을 수 있는 특정 코드가 없는 한 무언가를 이상의 구조에서 마음입니다.
당신은 기본적으로 원하는:
- 을 얻는 문자열의 길이를,그리고 창의 폭입니다.
- 어떻게 부르는 것들은 많은 걸릴 수 있습에서 원래의 문자열을 원칙으로 하고 있으나 창 폭-3.전화 k.
- 에 따라할지 여부를 넣어임에서 중간에서 오른쪽 손 끝에,하나는 첫 번째 층(k/2)문자 한쪽 끝에서,연결된"...",그 후에 연결되어 마지막 바닥(k/2)문자는(아마 한 글자를 더 필요하기 때문에 사단);또는 첫 번째 k 문자,ollowed 여"...".
나는 생각 Smashery 의 대답은 좋은 출발점이 될 수 있습니다.을 얻을 수있는 방법 중 하나는 최종 결과하는 것입 테스트 코드 테스트 입력하고 원하는 출력이 있습니다.일단 당신이 좋은 설정의 테스트 설정,구현할 수 있습니다 당신의 문자열 조작 코드를 얻을 때까지 귀하의 모든 테스트를 통과합니다.
- 계산 폭의 텍스트( 기반으로 글꼴)
에서 사용하는 경우 MFC API GetOutputTextExtent 당신을 얻을 것이 값으로 설정합니다.
는 경우 폭을 초과정 특정 폭을 계산하는 타원 폭 첫:
ellipseWidth=산의 너비(...)
을 제거하는 문자열 부분으로 폭 ellipseWidth 끝에서 추가 타원입니다.
다음과 같습니다.안녕하세요...
에 대한 관심이있는 사람들을위한 완전한 일상적인,이것은 나 응답 :
/**
* Returns a string abbreviation
* example: "hello world" -> "...orld" or "hell..." or "he...rd" or "h...rld"
*
* style:
0: clip left
1: clip right
2: clip middle
3: pretty middle
*/
CString*
strabbr(
CDC* pdc,
const char* s,
const int area_width,
int style )
{
if ( !pdc || !s || !*s ) return new CString;
int len = strlen(s);
if ( pdc->GetTextExtent(s, len).cx <= area_width ) return new CString(s);
int dots_width = pdc->GetTextExtent("...", 3).cx;
if ( dots_width >= area_width ) return new CString;
// My algorithm uses 'left' and 'right' parts of the string, by turns.
int n = len;
int m = 1;
int n_width = 0;
int m_width = 0;
int tmpwidth;
// fromleft indicates where the clip is done so I can 'get' chars from the other part
bool fromleft = (style == 3 && n % 2 == 0)? false : (style > 0);
while ( TRUE ) {
if ( n_width + m_width + dots_width > area_width ) break;
if ( n <= m ) break; // keep my sanity check (WTF), it should never happen 'cause of the above line
// Here are extra 'swap turn' conditions
if ( style == 3 && (!(n & 1)) )
fromleft = (!fromleft);
else if ( style < 2 )
fromleft = (!fromleft); // (1)'disables' turn swapping for styles 0, 1
if ( fromleft ) {
pdc->GetCharWidth(*(s+n-1), *(s+n-1), &tmpwidth);
n_width += tmpwidth;
n--;
}
else {
pdc->GetCharWidth(*(s+m-1), *(s+m-1), &tmpwidth);
m_width += tmpwidth;
m++;
}
fromleft = (!fromleft); // (1)
}
if ( fromleft ) m--; else n++;
// Final steps
// 1. CString version
CString* abbr = new CString;
abbr->Format("%*.*s...%*.*s", m-1, m-1, s, len-n, len-n, s + n);
return abbr;
/* 2. char* version, if you dont want to use CString (efficiency), replace CString with char*,
new CString with _strdup("") and use this code for the final steps:
char* abbr = (char*)malloc(m + (len-n) + 3 +1);
strncpy(abbr, s, m-1);
strcpy(abbr + (m-1), "...");
strncpy(abbr+ (m-1) + 3, s + n, len-n);
abbr[(m-1) + (len-n) + 3] = 0;
return abbr;
*/
}