Je voulais imprimer tout mon tableau [i] sur une seule ligne dans une nouvelle fonction, mais tout a été mal aligné dans le tableau de ma sortie.
Je ne trouve pas où est le problème:
Subject Name Subject Code Credit --------------------------------------------------------------- Programming Technique DCS1053 3 Current Issues in ICT DCS1062 3 Object Oriented Programming DCS1083 3
Voici le résultat.
Les valeurs du tableau sont toutes faussées, certaines sont également dupliquées, ce qui n'est pas ce que je voulais que ce soit:
How many subject to be registered: 3 SUBJECT CODE 1.: DCS1053 SUBJECT NAME: Programming Technique SUBJECT CREDIT: 3 SUBJECT CODE 2.: DCS1062 SUBJECT NAME: Current Issues in ICT SUBJECT CREDIT: 3 SUBJECT CODE 3.: DCS1083 SUBJECT NAME: Object Oriented Programming SUBJECT CREDIT: 3 Subject Name Subject Code Credit ------------------------------------------------------------------ Programming Technique DCS1053 3 Current Issues in ICT DCS1062 3 Object Oriented Programming DCS1083 3 Process returned 3 (0x3) execution time : 53.708 s Press any key to continue.
Je voudrais que ma sortie ressemble à ceci:
#include <stdio.h>
#include <stdlib.h>
void userInput();
void formOutput(int, char (*)[50], char (*)[10], int *);
void main()
{
userInput();
}
void userInput()
{ int totalSubj;
printf("\nHow many subject to be registered: ");
scanf("%d",&totalSubj);
char subjCode[totalSubj][10], subjName[totalSubj][50];
int subjCred[totalSubj];
for(int i=0;i<totalSubj;i++)
{
printf("\nSUBJECT CODE %d.: ",i+1);
scanf("%s",&subjCode[i]);
printf("SUBJECT NAME: ");
fgets(subjName[i],50,stdin);
printf("SUBJECT CREDIT: ");
scanf("%d",&subjCred[i]);
}
formOutput(totalSubj, subjName, subjCode, subjCred);
}
void formOutput(int subjTotal, char nameSub[][50], char codeSub[][10], int credSub[])
{
printf("Subject Name Subject Code Credit\n");
printf("------------------------------------------------------------------");
for(int i=0;i<subjTotal;i++)
{
printf("\n%s ",nameSub[i]);
printf("%s\t\t",codeSub[i]);
printf("%d",credSub[i]);
}
}
4 Réponses :
vous lisez le nom du sujet en utilisant fgets pour que l'on contienne la nouvelle ligne et que vous l'imprimiez => le sujet est seul sur sa ligne, puis sur la ligne suivante vous avez le code et le crédit pour lire une chaîne contenant des espaces sauf newline vous pouvez utiliser scanf :
scanf(" %49[^\n]", &subjName[i]);
l'espace au début du format permet de supprimer les espaces / newline / .. avant le premier caractère non espace, qui permet de contourner la nouvelle ligne enter après le code
pour avoir votre sortie comme vous vous attendez, vous ne pouvez pas écrire une quantité fixe d'espace / tabulation, utilisez les capacités de printf pour écrire sur une largeur donnée
aussi il n'est pas cohérent d'avoir une largeur à imprimer inférieure à la taille des champs que vous pouvez lire
@Yunnosch non car les caractères à l'intérieur de [] ne sont pas lus
@Yunnosch la nouvelle ligne est contournée en lisant le crédit qui est un nombre
Oui, c'est l'explication. Pensez à l'expliquer plus explicitement, plus précisément dans la réponse. Juste pour le rendre évident pour les inexpérimentés (et les nitpickers comme moi ... ;-)).
Essayez ce code dans formOutput()
printf("Subject Name \t\t\tSubject Code\t\tCredit\n");
printf("-------------\t\t\t------------\t\t------\n");
int i=0;
for( i=0;i<subjTotal;i++)
{
printf("\n%s\t\t\t",nameSub[i]);
printf("%s\t\t",codeSub[i]);
printf("%d\n",credSub[i]);
}
Pourquoi? Quelle est la différence? Comment cela est-il censé aider?
écoutez vous prenez le nom du sujet qui a de l'espace, veuillez donc utiliser scanf ("% [^ \ n] s", & subjName [i]); pendant la numérisation. et le formage de la pièce est quelque chose que vous devez vérifier par essai
Vous citez la solution au problème principal de l'autre réponse - dans un commentaire. Votre réponse elle-même ne fournit pas de solution. Deviner la taille des entrées et espérer que certains tabulateurs corrigent l'alignement est une approche ... optimiste ... au mieux.
Les s de fin de scanf ("% [^ \ n] s", ne servent à rien. Mieux vaut le supprimer.
La fonction fgets () prend la nouvelle ligne comme entrée et insère le caractère de nouvelle ligne dans la variable et vous obtenez une sortie désastreuse.
Ce code peut vous aider à résoudre votre problème (pratique explique sont ajoutés dans les commentaires):
How many subjects to be registered? 3 SUBJECT CODE 1.: DCS1053 SUBJECT NAME: Programming Technique SUBJECT CREDIT: 3 SUBJECT CODE 2.: DCS1062 SUBJECT NAME: Current Issues in ICT SUBJECT CREDIT: 3 SUBJECT CODE 3.: DCS1083 SUBJECT NAME: Object Oriented Programming SUBJECT CREDIT: 3 Subject Name Subject Code Credit --------------------------------------------------------------- Programming Technique DCS1053 3 Current Issues in ICT DCS1062 3 Object Oriented Programming DCS1083 3
Exemple de sortie:
#include <stdio.h>
#include <string.h>
// defining macros the maximum lengths of array as a constant
#define SUB_NAME_MAX 50
#define SUB_CODE_MAX 10
// function signature
void formed_output(int, char [][SUB_NAME_MAX], char [][SUB_CODE_MAX], int[]);
int main(void) {
int total;
printf("How many subjects to be registered? ");
scanf("%d", &total);
char sub_code[total][SUB_CODE_MAX], sub_name[total][SUB_NAME_MAX];
int sub_credit[total];
for (int i = 0; i < total; i++) {
printf("\nSUBJECT CODE %d.: ",i+1);
scanf("%s", &sub_code[i]);
printf("SUBJECT NAME: ");
fseek(stdin, 0, SEEK_END); // to avoid skipping user input
fgets(sub_name[i], SUB_NAME_MAX, stdin);
char *pos;
if ((pos=strchr(sub_name[i], '\n')) != NULL)
*pos = '\0'; // this one is the trick which will help to
// remove newline of each 'sub_name' array
printf("SUBJECT CREDIT: ");
scanf("%d", &sub_credit[i]);
}
printf("\n"); // for good-looking purpose
formed_output(total, sub_name, sub_code, sub_credit);
return 0;
}
void formed_output(int total, char name[][SUB_NAME_MAX], char code[][SUB_CODE_MAX], int cred[]) {
printf("Subject Name Subject Code Credit\n");
printf("---------------------------------------------------------------\n");
for(int i = 0; i < total; i++) {
printf("%-35s", name[i]); // left-justified for next 35 places
printf("%-22s", code[i]); // left-justified for next 22 places
printf("%d \n", cred[i]);
}
}
comme je le dis dans ma réponse, vous pouvez vous simplifier la vie en faisant scanf ("% 49 [^ \ n]", & subjName [i]);
tout est mal aligné dans le tableau de ma sortie.
fgets ()conserve un'\ n'qu'il a pu lire.
fgets ()etscanf ()ne fonctionnent pas bien ensemble.
Évitez d'utiliser les deux
fgets ()avecscanf (). Le premier lit une ligne , le deuxième non.Avec les entrées line , utilisez
fgets (). Utilisez des limitations de largeur lors du remplissage d'un tableau de caractères.L'utilisation de
fgets ()avecsscanf ()est OK.void userInput() { char buf[100]; int totalSubj; printf("\nHow many subject to be registered: "); fgets(buf, sizeof buf, stdin); sscanf(buf, "%d", &total); char subjCode[totalSubj][10], subjName[totalSubj][50]; int subjCred[totalSubj]; for (int i=0; i<totalSubj; i++) { printf("\nSUBJECT CODE %d.: ",i+1); fgets(buf, sizeof buf, stdin); sscanf(buf, "%9s", subjCode[i]); // & not used when calling with an array printf("SUBJECT NAME: "); fgets(buf, sizeof buf, stdin); sscanf(buf, "%49s", subjName[i]); printf("SUBJECT CREDIT: "); fgets(buf, sizeof buf, stdin); sscanf(buf, "%d",&subjCred[i]); } formOutput(totalSubj, subjName, subjCode, subjCred); }
À quoi souhaitez-vous que la sortie ressemble? Quelles sont vos attentes concernant l'effet de
'\ t'?subjName [totalSubj] [20]ne correspond pas àfgets (subjName [i], 50, stdin);. Pourquoi dites-vous àfgetsd'écrire50chars dans une mémoire tampon de20?"Technique de programmation"comporte 22 caractères. Selon vous, combien d'espace est disponible là où vous essayez de le stocker?voyez que vous utilisez un grand nom comme nom de sujet, alors assurez-vous de laisser un espace approprié. utilisez plusieurs fois
\ tet exécutez et essayez. et voyez ce qui fonctionne parfaitement pour vousExpliquer que dans un commentaire n'a pas vraiment fonctionné hein? Pourquoi ne pas modifier la question et donner ces détails là-bas, au lieu de les déformer et de les masquer ici dans les commentaires?
@mch Merci d'avoir informé, cependant la sortie est toujours la même bien que je l'ai corrigée à 50
@Yunnosch J'ai mis à jour le message, merci.
Je recommande de modifier à nouveau et d'expliquer en détail votre compréhension des zones de mémoire que vous utilisez dans votre code. Quelle est leur taille? Où sont-ils utilisés? De quelle taille ont-ils besoin pour ce que vous en faites? N'hésitez pas à indiquer où vous devinez. Référez-vous aux commentaires ci-dessus dans les commentaires pour donner votre avis. Demandez spécifiquement à quelles lignes ces commentaires se réfèrent si nécessaire.
scanf ("% s", & subjCode [i]);==>scanf ("% s", subjCode [i]);.fgetsécrit également la nouvelle ligne dans le tampon, vous ne le supprimez pas.@AnkitMishra Merci, j'espère les avoir dans la même ligne, mais le "nom du sujet" et le "code du sujet" sont toujours sur des lignes différentes bien que je n'ai pas ajouté \ n ou \ t entre eux.
il est évident que s'ils ne rentrent pas dans l'écran, ils utiliseront la deuxième ligne.
Veuillez modifier votre code pour créer des marqueurs de sortie qui permettent de savoir d'où viennent les espaces / retours à la ligne indésirables. Par exemple.
printf ("\ n <% s>", nomSub [i]); printf ("(% s) \ t \ t", codeSub [i]); printf ("[% d]", cr edSub [i]);et afficher la sortie de cela.Connaissez-vous ce détail dans en.cppreference.com/w/c/io/fgets "L'analyse s'arrête si un caractère de nouvelle ligne est trouvé, auquel cas str contiendra ce caractère de nouvelle ligne ..."?