programing

C에서 이와 같은 번호를 정렬하려면 어떻게 해야 합니까?

elecom 2023. 10. 30. 20:33
반응형

C에서 이와 같은 번호를 정렬하려면 어떻게 해야 합니까?

다음 예제와 같이 C의 일련의 숫자를 printf()와 정렬해야 합니다.

-------1
-------5
------50
-----100
----1000

물론 그 모든 것들 사이에 숫자가 있지만 당면한 문제와는 관련이 없습니다.아, 대시는 띄어쓰기로 생각하고, 원하는 걸 이해하기 쉽도록 대시를 사용했습니다.

저는 이것밖에 할 수 없습니다.

----1---
----5---
----50--
----100-
----1000

또는 이것:

---1
---5
--50
-100
1000

그러나 이 중 어느 것도 제가 원하는 것이 아니며 printf()만으로는 첫 번째 예제에 표시된 것을 달성할 수 없습니다.가능할까요?

편집:
미안해요 여러분, 제가 너무 급해서 제 설명을 잘 못했는데...마지막 예와 "%8d"와 같은 것을 사용하는 모든 제안은 작동하지 않습니다. 왜냐하면 마지막 숫자가 1000이지만 반드시 1000이나 100이나 10까지 가는 것은 아니기 때문입니다.

나는 표시되는 숫자와 상관없이 가장 큰 숫자에 대해 기껏해야 4개의 선두 칸만 원합니다.1부터 1000까지의 숫자(A)와 1부터 100까지의 숫자(B)를 표시해야 한다고 가정해 보겠습니다. 두 경우 모두 "%4d"를 사용하면 다음과 같은 결과가 나옵니다.

A:

---1
....
1000

내가 원하는 결과물이...

B:

---1
....
-100

제가 원하는 출력이 아니라, 사실 저는 이것을 원합니다.

--1
...
100

하지만 말씀드린 것처럼 정확한 숫자를 인쇄해야 하는 숫자는 잘 모르겠어요, 숫자는 한 자리, 숫자는 두 자리, 세 자리 이상일 수도 있고, 기능은 모두 준비되어 있어야 합니다.그리고 저는 4개의 추가 리드 공간을 원하지만 그것과는 관련이 없습니다.

편집 2: 제가 원하는 것, 제가 필요한 방식으로는 불가능한 것 같습니다(David Thornley와 Blank Xavier의 답변과 제 의견 확인).시간 내주셔서 감사합니다.

왜가.printf("%8d\n", intval);당신을 위해 일하지 않습니까?그것은...

"작동하지 않는" 예제에 대한 형식 문자열을 표시하지 않으셨기 때문에 다른 설명을 드려야 할지 모르겠습니다.

#include <stdio.h>

int
main(void)
{
        int i;
        for (i = 1; i <= 10000; i*=10) {
                printf("[%8d]\n", i);
        }
        return (0);
}

$ ./printftest
[       1]
[      10]
[     100]
[    1000]
[   10000]

EDIT: 질문의 해명에 대한 답변:

#include <math.h>
int maxval = 1000;
int width = round(1+log(maxval)/log(10));
...
printf("%*d\n", width, intval);

너비 계산은 로그 베이스 10 + 1을 계산하며, 이는 자릿수를 나타냅니다.팬시*형식 문자열의 값에 변수를 사용할 수 있습니다.

주어진 실행에 대한 최대치를 알아야 하지만, 어떤 언어나 연필과 종이로도 가능한 방법이 없습니다.

내가 사용하는 Harbison & Steel에서 이것을 찾아보니..

필드의 최대 너비를 결정합니다.

int max_width, value_to_print;
max_width = 8;
value_to_print = 1000;
printf("%*d\n", max_width, value_to_print);

max_width는 형식이어야 합니다.int별표를 사용하려면 공간을 얼마나 확보할지에 따라 계산해야 합니다.고객님의 경우에는 가장 큰 수의 최대 너비를 계산하고 4를 더해야 합니다.

    printf("%8d\n",1);
    printf("%8d\n",10);
    printf("%8d\n",100);
    printf("%8d\n",1000);

[저는 이 질문이 100만 년 전의 일이라는 것을 알고 있지만, 그 중심에는 OP, 프로그래밍의 교육학, 가정 만들기에 대한 더 깊은 질문(또는 두 가지)이 있습니다.]

모드를 포함한 몇몇 사람들은 이것이 불가능하다고 제안했습니다.그리고, 가장 명백한 맥락을 포함해서 어떤 것들은, 그렇습니다.하지만 그것이 OP에게 즉각적으로 명백하지 않다는 것을 보는 것은 흥미롭습니다.

불가능성은 컨텍스트가 C에서 컴파일된 실행 파일을 라인 지향 텍스트 콘솔(예: 콘솔+sh 또는 X-term+csh 또는 터미널+bash)에서 실행 중이라고 가정하는데, 이는 매우 합리적인 가정입니다.하지만 "올바른" 대답을 한다는 사실 (")%8d")는 OP에 충분하지 않았습니다. 또한 명백하지 않다는 것은 근처에 꽤 큰 벌레 통조림이 있다는 것을 의미합니다.

저주(및 그 다양한 변형)를 생각해 보십시오.화면에서 "화면"을 탐색하고 커서를 "이동"하고 텍스트 기반 출력의 일부(창)를 "다시 칠"할 수 있습니다.Curses 컨텍스트에서 수행할 수 있습니다. 즉, "창"의 크기를 동적으로 조정하여 더 큰 수를 수용할 수 있습니다.하지만 저주조차도 화면의 "그림"추상일 뿐입니다.C에서 Curses를 구현했다고 해서 "엄격하게 C"가 되는 것은 아니기 때문에 아무도 제안하지 않았습니다.좋아.

하지만 이게 무슨 뜻일까요?응답을 위해 다음을(를)"불가능하다"는 말이 맞다면, 그것은 우리가 런타임 시스템에 대해 무언가를 말하고 있다는 것을 의미합니다.다시 말해서, 이것은 이론적이지 않습니다. ("어떻게 정적으로 할당된 배열을 정렬할 수 있습니까?ints?"), 이는 런타임의 어떤 측면도 완전히 무시하는 "닫힌 시스템"으로 설명될 수 있습니다.

하지만, 이 경우에는 I/O가 있습니다. 구체적으로,printf(). 하지만 거기서 더 재미있는 말을 할 수 있는 기회가 생깁니다. (인정하건대 질문자가 이 정도로 깊이 파고들지는 않았을 것입니다.)

다른 가정 집합을 사용한다고 가정합니다.OP가 합리적으로 "똑똑"하고 라인 지향 스트림에서 이전의 라인을 편집하는 것이 불가능하다는 것을 이해한다고 가정합니다(라인 프린터가 출력한 문자의 가로 위치를 어떻게 수정하시겠습니까?). 또한 OP가 단지 숙제를 하는 아이가 아니라 그것이 "꼼수" 질문이라는 것을 깨닫지 못한다고 가정합니다."스트림 추상화"의 의미에 대한 탐구를 놀리기 위한 의도로.또한 OP가 "잠깐만...C의 런타임 환경이 STDOUT의 아이디어를 지원한다면(그리고 STDOUT이 추상화에 불과하다면) 1) 세로 스크롤은 가능하지만 2) 위치 설정 가능한 커서를 지원하는 터미널 추상화를 갖는 것이 합리적이지 않은 이유는 무엇입니까?둘 다 화면에서 움직이는 텍스트입니다."

우리가 답하려는 질문이 그것이라면, 당신은 다음과 같은 것들까지 바라보기만 하면 될 것이기 때문입니다.

ANSI 탈출 코드

다음을 확인합니다.

거의 모든 비디오 단말기 제조사들이 벤더별 이스케이프 시퀀스를 추가하여 화면의 임의의 위치에 커서를 두는 등의 작업을 수행했습니다.예를 들어, VT52 단말기는 ESC 문자, Y 문자를 보낸 다음 x,y 위치에 32를 더한 숫자 값을 나타내는 두 문자(따라서 ASCII 공간 문자에서 시작하여 제어 문자를 피함)를 전송하여 화면의 x,y 위치에 커서를 놓을 수 있도록 했습니다.Hazeltine 1500은 ~, DC1을 사용하여 호출한 다음 쉼표로 구분된 X 및 Y 위치를 사용하여 유사한 기능을 가지고 있습니다.이 점에서 두 터미널은 동일한 기능을 가지고 있지만, 이들을 호출하기 위해서는 서로 다른 제어 시퀀스를 사용해야 했습니다.

이러한 순서를 지원하는 최초의 인기있는 비디오 단말기는 1978년에 소개된 디지털 VT100입니다.이 모델은 시장에서 매우 성공적이었고, 이 모델은 다양한 VT100 클론을 촉발시켰으며, 그 중 가장 초기의 것과 가장 인기 있는 것은 1979년의 훨씬 더 저렴한 Zenith Z-19였습니다.Qume QVT-108, Televideo TVI-970, Wyse WY-99GT는 물론, 다른 여러 브랜드에서 호환성 정도가 다양한 옵션인 "VT100" 또는 "VT103" 또는 "ANSI" 모드도 포함되었습니다.이러한 인기는 점차 탈출 시퀀스가 작동한다고 가정하는 소프트웨어(특히 게시판 시스템 및 기타 온라인 서비스)로 이어졌고, 이를 지원하는 거의 모든 새로운 단말기 및 에뮬레이터 프로그램으로 이어졌습니다.

그것은 일찍이 1978년에 가능했습니다.C 자체가 1972년생이고, 1978년 K&R 버전이 탄생했습니다.당시 "ANSI" 탈출 시퀀스가 존재했다면 "C"에 대한 답이 있습니다. "자, 단말기가 VT100 지원이라고 가정하면"이라고 규정할 수 있습니다.그런데 ANSI를 지원하지 않는 콘솔이 탈출한다고요?짐작하셨겠지요: 윈도우 & 도스 콘솔.하지만 거의 모든 플랫폼(Unice, Vaxen, Mac OS, Linux)에서 기대할 수 있습니다.

TL;DR - 런타임 환경에 대한 가정을 제시하지 않고는 제시할 수 있는 합리적인 답변은 없습니다.대부분의 가동 시간(데스크톱-컴퓨터-80년대와 90년대의 시장 점유율을 '대부분' 계산하기 위해 사용하지 않는 한)은 (VT-52 이후로) 불가능하다고 말하는 것은 전적으로 정당하다고 생각하지 않습니다. 단지 작업이 가능하기 위해서는 작업의 규모가 완전히 다르며 그렇게 간단하지도 않습니다.%8d작전팀이 알고 있는 것 같았어요

우리는 단지 가정을 명확히 해야 합니다.

또한 I/O가 예외적이라고 생각하지 않도록, 즉 런타임이나 심지어 하드웨어에 대해 생각해 볼 필요가 있는 유일한 시간은 IEEE 754 Floating Point 예외 처리에 대해 자세히 알아 보십시오.관심있는 분들을 위해:

인텔 부동 소수점 사례 연구

버클리 캘리포니아 대학의 윌리엄 카한 교수에 의하면, 1996년 6월에 고전적인 사건이 일어났습니다.위성을 들어 올리는 Ariane 5 로켓은 발사 직후 수레바퀴를 돌면서 프랑스령 기아나의 습지 위에 5억 달러 이상의 가치가 있는 탑재체를 흩뿌렸습니다.Kahan은 IEEE 754의 기본 예외 처리 사양을 무시한 프로그래밍 언어가 이 재앙의 원인일 수 있음을 발견했습니다.발사와 동시에 센서는 가속력이 너무 강해서 발사대에 있는 동안 로켓의 관성 유도를 재보정하기 위한 소프트웨어에서 정수로의 변환 오버플로우를 일으켰다고 보고했습니다.

그래서, 공간을 패딩으로 한 8자 넓이의 필드를 원하십니까?%8d을(를) 시도합니다.여기 참고 자료가 있습니다.

편집: 당신이 하려는 일은 인쇄물만으로는 다룰 수 없는 일입니다. 왜냐하면 그것은 당신이 쓰고 있는 가장 긴 숫자가 무엇인지 알 수 없기 때문입니다.인쇄를 수행하기 전에 가장 큰 숫자를 계산한 다음 필드의 너비로 사용할 자릿수를 계산해야 합니다.그런 다음 snprint for를 사용하여 현장에서 printf 형식을 만들 수 있습니다.

char format[20];
snprintf(format, 19, "%%%dd\\n", max_length);
while (got_output) {
    printf(format, number);
    got_output = still_got_output();
}

문자열로 변환한 다음 "%4.4s"를 형식 지정자로 사용합니다.이렇게 하면 고정 너비 형식이 됩니다.

제가 질문해본 결과, 가지고 계신 데이터에 따라 원하시는 패딩의 양이 달라질 것 같습니다.따라서 이에 대한 유일한 해결책은 인쇄 전에 데이터를 스캔하여 가장 넓은 데이터를 파악하고, 따라서 Asterix 연산자를 사용하여 인쇄에 전달할 수 있는 너비 값을 찾는 것입니다.

loop over data - get correct padding, put into width

printf( "%*d\n", width, datum );

너비를 미리 알 수 없는 경우 출력을 어떤 종류의 임시 버퍼에 준비하는 것이 가능한 유일한 대답입니다.소규모 보고서의 경우 입력이 경계가 될 때까지 데이터를 수집하고 출력을 지연하는 것이 가장 간단합니다.

대규모 보고서의 경우 수집된 데이터가 합리적인 메모리 한계를 초과할 경우 중간 파일이 필요할 수 있습니다.

데이터가 있으면 관용구를 사용하여 보고서로 후처리하는 것이 간단합니다.printf("%*d", width, value)각각의 값에 대하여

또는 출력 채널에서 랜덤 액세스를 허용하는 경우에는 기본 너비(짧은)를 가정한 보고서 초안을 작성하고 너비 가정을 위반할 때마다 다시 찾아 편집할 수 있습니다.이는 또한 해당 필드 외부의 보고서 라인을 악의 없는 방식으로 패딩하거나 지금까지의 출력을 읽기-수정-쓰기 프로세스로 대체하고 초안 파일을 포기할 수 있다고 가정합니다.

그러나 당신이 미리 정확한 폭을 예측할 수 없는 한, 어떤 형태의 투패스 알고리즘 없이는 당신이 원하는 것을 할 수 없을 것입니다.

편집된 문제를 보면, 제시할 가장 큰 숫자의 숫자를 찾은 다음, 그 숫자를 생성해야 합니다.printf()포맷 사용sprintf(), 또는 사용하기%*d숫자의 숫자가 int로 전달됨과 함께*그리고 그 값.일단 당신이 가장 큰 숫자를 얻었을 때(그리고 당신은 그것을 미리 결정해야 한다), 당신은 '정수 로그' 알고리즘으로 숫자를 결정할 수 있습니다(당신이 0에 도달하기 전에 당신은 몇 번을 10으로 나눌 수 있습니까), 또는 다음을 사용하여.snprintf()버퍼 길이가 0일 때, 형식은%d문자열의 경우 null입니다. 반환 값은 형식이 지정된 문자 수를 알려줍니다.

만약 여러분이 모르거나 그것의 출현에 앞서 최대 숫자를 결정할 수 없다면, 여러분은 염탐을 당하게 됩니다 - 할 수 있는 것이 없습니다.

#include<stdio.h>
int main()
{
 int i,j,n,b;
 printf("Enter no of rows ");
 scanf("%d",&n);
 b=n;
 for(i=1;i<=n;++i)
 {
    for(j=1;j<=i;j++)
    {
        printf("%*d",b,j);
        b=1;
    }
        b=n;
    b=b-i;
    printf("\n");


 }
 return 0;
}
fp = fopen("RKdata.dat","w");
fprintf(fp,"%5s %12s %20s %14s %15s %15s %15s\n","j","x","integrated","bessj2","bessj3","bessj4","bessj5");
for (j=1;j<=NSTEP;j+=1)
    fprintf(fp,"%5i\t %12.4f\t %14.6f\t %14.6f\t %14.6f\t %14.6f\t %14.6f\n",
    j,xx[j],y[6][j],bessj(2,xx[j]),bessj(3,xx[j]),bessj(4,xx[j]),bessj(5,xx[j]));
fclose(fp);

언급URL : https://stackoverflow.com/questions/757627/how-do-i-align-a-number-like-this-in-c

반응형