web-dev-qa-db-fra.com

Comment aligner un nombre comme celui-ci en C?

Je dois aligner une série de nombres en C avec printf () comme dans cet exemple:

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

Bien sûr, il y a des chiffres entre tous ceux-là, mais ce n'est pas pertinent pour le problème en question ... Oh, considérez les tirets comme des espaces, j'ai utilisé des tirets pour qu'il soit plus facile de comprendre ce que je veux.

Je ne peux que faire ceci:

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

Ou ca:

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

Mais rien de tout cela n'est ce que je veux et je ne peux pas atteindre ce qui est affiché dans le premier exemple en utilisant seulement printf (). Est-ce possible?

MODIFIER:
Désolé, j'étais pressé et je ne me suis pas bien expliqué ... Mon dernier exemple et toutes vos suggestions (pour utiliser quelque chose comme "% 8d") ne fonctionnent pas car, bien que le dernier nombre soit 1000, il ne va pas nécessairement jusqu'à 1000 ou même 100 ou 10 d'ailleurs.

Quel que soit le nombre de chiffres à afficher, je ne souhaite que 4 espaces au maximum pour le nombre le plus élevé. Disons que je dois afficher les chiffres de 1 à 1000 (A) et de 1 à 100 (B) et que j'utilise, pour les deux, "% 4d", ce serait la sortie:

UNE:

---1
....
1000

Quelle est la sortie que je veux ...

B:

---1
....
-100

Ce qui n'est pas la sortie que je veux, je veux en fait ceci:

--1
...
100

Mais comme je l'ai dit, je ne connais pas le nombre exact de chiffres que je dois imprimer, il peut avoir 1 chiffre, il peut en avoir 2, 3 ou plus, la fonction doit être préparée pour tous. Et je veux quatre espaces principaux supplémentaires, mais ce n'est pas pertinent.

EDIT 2: .__ Il semble que ce que je veux, de la façon dont j'en ai besoin, n’est pas possible (vérifiez David Thornley et Blank Xavier répond et mes commentaires). Merci à tous pour votre temps.

29
Ricardo Amaral

En regardant cela dans mon pratique Harbison & Steele ....

Déterminez la largeur maximale des champs.

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

N'oubliez pas que max_width doit être de type int pour que l'astérisque fonctionne, et vous devrez le calculer en fonction de l'espace que vous souhaitez obtenir. Dans votre cas, vous devrez calculer la largeur maximale du nombre le plus grand et ajouter 4.

44
David Thornley

Pourquoi printf("%8d\n", intval); ne fonctionne-t-il pas pour vous? Cela devrait...

Vous n'avez pas montré les chaînes de format pour aucun de vos exemples "ne fonctionne pas", donc je ne sais pas quoi vous dire d'autre.

#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: réponse à la clarification de la question:

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

Le calcul de la largeur calcule la base de journal 10 + 1, qui donne le nombre de chiffres. La fantaisie * vous permet d'utiliser la variable pour une valeur dans la chaîne de format.

Vous devez toujours connaître le maximum pour une série donnée, mais il n’ya aucune solution en ce sens, que ce soit dans une langue ou un crayon ou un papier.

44
dwc
    printf("%8d\n",1);
    printf("%8d\n",10);
    printf("%8d\n",100);
    printf("%8d\n",1000);
3
Alex B

Essayez de convertir en chaîne, puis utilisez "% 4.4s" comme spécificateur de format. Cela en fait un format de largeur fixe.

1
MM

Si vous ne pouvez pas connaître la largeur à l'avance, votre seule réponse possible dépendra de la mise en place de votre sortie dans un tampon temporaire quelconque. Pour les petits rapports, il serait plus simple de collecter les données et de différer la sortie jusqu'à ce que l'entrée soit liée.

Pour les rapports volumineux, un fichier intermédiaire peut être requis si les données collectées dépassent les limites de mémoire raisonnables.

Une fois que vous avez les données, il est simple de les post-traiter dans un rapport en utilisant l'idiome printf("%*d", width, value) pour chaque valeur.

Si le canal de sortie autorise un accès aléatoire, vous pouvez également rédiger un brouillon du rapport en supposant une largeur par défaut (courte), puis rechercher en arrière et le modifier chaque fois que votre hypothèse de largeur est violée. Cela suppose également que vous pouvez remplir les lignes de rapport en dehors de ce champ de manière anodine, ou que vous souhaitiez remplacer la sortie jusqu'à présent par un processus de lecture-modification-écriture et abandonner le fichier brouillon.

Mais à moins que vous ne puissiez prédire la largeur correcte à l'avance, il ne sera pas possible de faire ce que vous voulez sans une forme d'algorithme à deux passes.

0
RBerteig

D'après ce que je peux dire de la question, la quantité de remplissage que vous souhaitez varie en fonction des données dont vous disposez. Par conséquent, la seule solution consiste à numériser les données avant l'impression, afin de déterminer la donnée la plus large et de trouver une valeur de largeur que vous pouvez transmettre à printf à l'aide de l'opérateur astérisque, par ex.

loop over data - get correct padding, put into width

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

Donc, vous voulez un champ large de 8 caractères avec des espaces comme remplissage? Essayez "% 8d". Voici une référence .

EDIT: Ce que vous essayez de faire n'est pas quelque chose qui peut être géré par printf seul, car il ne saura pas quel est le plus long numéro que vous écrivez. Vous devrez calculer le nombre le plus élevé avant d’imprimer printfs, puis déterminer le nombre de chiffres à utiliser comme largeur de votre champ. Ensuite, vous pouvez utiliser snprintf ou similaire pour créer un format printf sur-le-champ.

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

En examinant la question modifiée, vous devez trouver le nombre de chiffres du plus grand nombre à présenter, puis générer le format printf() en utilisant sprintf() ou en utilisant %*d avec le nombre de chiffres passés en tant que entier pour le * et valeur. Une fois que vous avez le plus grand nombre (et que vous devez le déterminer à l'avance), vous pouvez déterminer le nombre de chiffres avec un algorithme de «logarithme entier» (combien de fois pouvez-vous diviser par 10 avant d'arriver à zéro), ou en utilisant snprintf() avec une longueur de tampon de zéro, le format %d et la valeur null pour la chaîne; la valeur de retour vous indique combien de caractères auraient été formatés.

Si vous ne savez pas et ne pouvez pas déterminer le nombre maximum en avance sur son apparence, vous êtes snooké - vous ne pouvez rien faire.

0
Jonathan Leffler
#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;
}
0
vino