C Program - Output is shown at next line without using newline character -
in code after typing user input when asked code has give output same.
this part of code given below prints output after output city_1[i].city
printed further output printed on newline.
in printf
statement didn't used "\n"
after "%s"
.
for (i = 0; <= k - 1; i++) { printf(" %s %d %f%", city_1[i].city, city_1[i].p, city_1[i].l); //printf("\n"); }
i'm using visual studio 2015 debugging code.
can , explain me in issue?
given below code:
#include <stdio.h> #include <stdlib.h> #include <process.h> //global-variable declartion #define max 1000 //global-structures declaration struct census { char city[max]; long int p; float l; }; //global-structure-variable declaration struct census cen[max] = { 0 }; //user-defined function struct census sortm_city(struct census city_1[]); struct census sortm_population(struct census popu[]); struct census sortm_literacy(struct census lite[]); void header(); void header() { printf("*-*-*-*-*census_info*-*-*-*-*"); printf("\n\n"); } //program starts here main() { //variable-declaration int = 0, j = 0, n = 0; char line[max] = { 0 }; char o = { 0 }; //function call-out header(); printf("enter no. of city : "); fgets(line, sizeof(line), stdin); sscanf_s(line, "%d", &j); printf("\n\n"); printf("enter name of city, population , literacy level"); printf("\n\n"); (i = 0; <= j - 1; i++) { printf("city no. %d - info :", + 1); printf("\n\n"); printf("city name : "); fgets(cen[i].city, max, stdin); printf("\n"); printf("population : "); fgets(line, sizeof(line), stdin); sscanf_s(line, "%d", &cen[i].p); printf("\n"); printf("literacy : "); fgets(line, sizeof(line), stdin); sscanf_s(line, "%f", &cen[i].l); printf("\n"); printf("_____________________________________"); printf("\n\n"); } printf("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* "); printf("census information"); printf(" *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*"); printf("\n\n"); (i = 0; <= j - 1; i++) { printf("city no. %d - info :", + 1); printf("\n\n"); printf("city name : %s", cen[i].city); printf("\n"); printf("population : %d", cen[i].p); printf("\n"); printf("literacy : %0.2f", cen[i].l); printf("\n"); printf("_____________________________________"); printf("\n\n"); } printf("enter 1 option following : \n\n"); printf("(a) sort list alphabetically. \n"); printf("(b) sort list based on literacy level. \n"); printf("(c) sort list based on population. \n\n"); printf("please type proper option. \n"); n = 0; while (n == 0) { scanf_s(" %c", &o); switch (o) { case 'a': sortm_city(cen, j); n = 1; break; case 'b': sortm_population(cen); n = 1; break; case 'c': sortm_literacy(cen); n = 1; break; default: printf("option invalid \n"); printf("please type proper option. \n"); n = 0; break; } } //terminal-pause system("pause"); } struct census sortm_city(struct census city_1[], int k) { int = 0, j = 0; //for transferring float b = 0; int s = 0; char line_0[max] = { 0 }; (i = 1; <= k - 1; i++) { (j = 1; j <= k - 1; j++) { if (strcmp(city_1[j - 1].city, city_1[j].city) > 0) { //sorting list alphabetically. strcpy(line_0, city_1[j - 1].city); strcpy(city_1[j - 1].city, city_1[j].city); strcpy(city_1[j].city, line_0); //copying population , literacy right place. //population : s = city_1[j - 1].p; city_1[j - 1].p = city_1[j].p; city_1[j].p = s; //literacy : b = city_1[j - 1].l; city_1[j - 1].l = city_1[j].l; city_1[j].l = b; } } } printf("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* "); printf("sorted list in alphabetical order"); printf(" *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*"); printf("\n\n"); printf("___________________________________________________\n"); printf("| *city name* | population | literacy | \n"); (i = 0; <= k - 1; i++) { printf(" %s %d %f%", city_1[i].city, city_1[i].p, city_1[i].l); //printf("\n"); } } struct census sortm_population(struct census popu[]) { printf("-------"); } struct census sortm_literacy(struct census lite[]) { printf("-------"); }
the problem comes linefeed fgets()
leaves @ end of line read stream. if buffer short or if last line in file not end line terminator, buffer not end \n
before final \0
, in other cases, will.
a simple way remove linefeed if present is:
line[strcspn(line, "\n")] = '\0';
it overwrites \n
if finds one, otherwise overwrites \0
\0
.
note should test return value of fgets()
, returns null
if fails read line @ end of file.
note simpler , more idiomatic write for
loops way:
for (i = 0; < j; i++) { ... }
the index 0
included , index j
won't be, same syntax, simpler more readable way.
you use qsort
sort table 3 different comparison functions.
also note definition of main()
obsolete , incorrect c99 , later c standards. should either write int main(void)
or int main(int argc, char *argv[])
.
here list of issues:
- you define census member
p
long int
use%d
read viasscanf
, printprintf
, proper format%ld
. - you define sortm_xxx functions returning
struct census
, incorrect, ,sortm_city
indeed returns nothing, should definedvoid
. header
should declared , definedvoid header(void)
main
should definedint main(void)
- you use
scanf_s
,sscanf_s
. these functions recommended visual studio, not available on other systems,scanf
,sscanf
, can used safely precautions,%s
,%[
formats, not use here anyway. fgets
leaves\n
@ end of line. should check retuen value detect premature end of file , strip\n
. defined utility functionxgets()
both.strcspn()
returns number of characters string argument not among list given second string argument.- the printing code uses
%f
literacy level, resulting in 6 decimal places (the default), should use%7.2f
2 decimal places , align column contents. - you must use
%%
print%
characterprintf
. - i added alignment arguments in
printf
format string align output, assuming fixed width font:"| %-15s | %10ld | %7.2f%% |"
.%-15s
pads city name 15 characters spaces after city name,%10ld
pads population 10 characters spaces before population figure.%7.2f
produces 2 decimal places , pads spaces before literacy figure upto 7 characters before.
. - i used
qsort
, defined 3 comparison functions 3 sort options. - i moved code printing census data separate function. is better factorize code way write less code , avoid inconsistencies when later fix bugs.
here corrected , simplified version:
#include <stdio.h> #include <stdlib.h> #include <string.h> //global-variable declartion #define max 1000 //global-structures declaration struct census { char city[max]; long int p; float l; }; //global-structure-variable declaration struct census cen[max] = { 0 }; //user-defined function void header(void); void sortm_city(struct census cp[], int n); void sortm_population(struct census cp[], int n); void sortm_literacy(struct census cp[], int n); void print_census(struct census cp[], int k, const char *legend); void header(void) { printf("*-*-*-*-*census_info*-*-*-*-*"); printf("\n\n"); } char *xgets(char *dest, int size, file *fp) { /* read line user */ if (!fgets(dest, size, fp)) { /* read failed, end of file detected */ printf("premature end of file\n"); exit(1); } /* strip \n if present */ dest[strcspn(dest, "\n")] = '\0'; return dest; } //program starts here int main(void) { //variable-declaration int = 0, j = 0, n = 0; char line[max] = { 0 }; char o = { 0 }; //function call-out header(); printf("enter no. of city : "); xgets(line, sizeof(line), stdin); if (sscanf(line, "%d", &j) != 1) return 1; printf("\n\n"); printf("enter name of city, population , literacy level"); printf("\n\n"); (i = 0; < j; i++) { printf("city no. %d - info :", + 1); printf("\n\n"); printf("city name : "); xgets(cen[i].city, max, stdin); printf("\n"); printf("population : "); xgets(line, sizeof(line), stdin); sscanf(line, "%ld", &cen[i].p); printf("\n"); printf("literacy : "); xgets(line, sizeof(line), stdin); sscanf(line, "%f", &cen[i].l); printf("\n"); printf("_____________________________________"); printf("\n\n"); } printf("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* "); printf("census information"); printf(" *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*"); printf("\n\n"); (i = 0; < j; i++) { printf("city no. %d - info :", + 1); printf("\n\n"); printf("city name : %s", cen[i].city); printf("\n"); printf("population : %ld", cen[i].p); printf("\n"); printf("literacy : %0.2f", cen[i].l); printf("\n"); printf("_____________________________________"); printf("\n\n"); } printf("enter 1 option following : \n\n"); printf("(a) sort list alphabetically. \n"); printf("(b) sort list based on literacy level. \n"); printf("(c) sort list based on population. \n\n"); printf("please type proper option. \n"); n = 0; while (n == 0) { scanf(" %c", &o); switch (o) { case 'a': sortm_city(cen, j); n = 1; break; case 'b': sortm_population(cen, j); n = 1; break; case 'c': sortm_literacy(cen, j); n = 1; break; default: printf("option invalid \n"); printf("please type proper option. \n"); n = 0; break; } } //terminal-pause system("pause"); } void print_census(struct census cp[], int k, const char *legend) { int i; printf("*-*-*-*-*-*-*-*- %s *-*-*-*-*-*-*-*-*-*", legend); printf("\n\n"); printf("___________________________________________________\n"); printf("| city name | population | literacy |\n"); printf("___________________________________________________\n"); (i = 0; < k; i++) { printf("| %-15s | %10ld | %7.2f%% |", cp[i].city, cp[i].p, cp[i].l); printf("\n"); } printf("___________________________________________________\n"); printf("\n\n"); } int compare_census_city(const void *a, const void *b) { const struct census *ca = a; const struct census *cb = b; return strcmp(ca->city, cb->city); } int compare_census_population(const void *a, const void *b) { const struct census *ca = a; const struct census *cb = b; if (ca->p > cb->p) return -1; if (ca->p < cb->p) return 1; return 0; } int compare_census_literacy(const void *a, const void *b) { const struct census *ca = a; const struct census *cb = b; if (ca->l > cb->l) return -1; if (ca->l < cb->l) return 1; return 0; } void sortm_city(struct census cp[], int n) { qsort(cp, n, sizeof(struct census), compare_census_city); print_census(cp, n, "sorted list in alphabetical order"); } void sortm_population(struct census cp[], int n) { qsort(cp, n, sizeof(struct census), compare_census_population); print_census(cp, n, "sorted list decreasing popupation"); } void sortm_literacy(struct census cp[], int n) { qsort(cp, n, sizeof(struct census), compare_census_literacy); print_census(cp, n, "sorted list in decreasing literacy level"); }
Comments
Post a Comment