문제

고 싶 문자열로 특정 폭입니다.예를 들어,"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;
}

다른 팁

그것은 정말 아주 사소한;나는 생각하지 않을 찾을 수 있는 특정 코드가 없는 한 무언가를 이상의 구조에서 마음입니다.

당신은 기본적으로 원하는:

  1. 을 얻는 문자열의 길이를,그리고 창의 폭입니다.
  2. 어떻게 부르는 것들은 많은 걸릴 수 있습에서 원래의 문자열을 원칙으로 하고 있으나 창 폭-3.전화 k.
  3. 에 따라할지 여부를 넣어임에서 중간에서 오른쪽 손 끝에,하나는 첫 번째 층(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;
  */
}

원하는 경우에는"표준"임 형식으로("안녕하세요")사용할 수 있습니다 DrawText (나 equivalient MFC 기능)기능을 통과 DT_END_ELLIPSIS.

체크아웃도 DT_WORD_ELLIPSIS (그것은 잘 어떤 단어를 적합하지 않는 사각형에서 추가 타원)또는 DT_PATH_ELLIPSIS (어떤기를 표시하는 긴 경로).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top