在此代码中输入所有用户输入后,当被要求代码必须为其输出时。
这是下面给出的代码的一部分,它打印输出但在打印city_1[i].city
的输出后,更新的输出打印在换行符上。
在printf
声明中,"\n"
之后我没有使用"%s"
。
for (i = 0; i <= k - 1; i++) {
printf(" %s %d %f%", city_1[i].city, city_1[i].p, city_1[i].l);
//printf("\n");
}
我正在使用 Visual Studio 2015 来调试我的代码。
任何人都可以在这个问题上帮助解释我吗?
以下是我的代码:
#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 i = 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 and Literacy level");
printf("\n\n");
for (i = 0; i <= j - 1; i++) {
printf("City No. %d - Info :", i + 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");
for (i = 0; i <= j - 1; i++) {
printf("City No. %d - Info :", i + 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 one option from the following : \n\n");
printf("(a) To Sort the List Alphabetically. \n");
printf("(b) To Sort the List based on Literacy Level. \n");
printf("(c) To Sort the List based on Population. \n\n");
printf("Please type a 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 a proper option. \n");
n = 0;
break;
}
}
//TERMINAL-PAUSE
system("pause");
}
struct census sortm_city(struct census city_1[], int k) {
int i = 0, j = 0;
//FOR TRANSFERRING
float b = 0;
int s = 0;
char line_0[MAX] = { 0 };
for (i = 1; i <= k - 1; i++) {
for (j = 1; j <= k - 1; j++) {
if (strcmp(city_1[j - 1].city, city_1[j].city) > 0) {
//SORTING THE 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 AND LITERACY TO 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");
for (i = 0; i <= 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("-------");
}
答案 0 :(得分:5)
fgets
包含用户在返回的字符串中键入的\n
字符。因此,当您打印该字符串时,您将获得一个新行。
答案 1 :(得分:1)
问题来自于fgets()
在从流中读取的行末尾留下的换行符。如果缓冲区太短或者文件中的最后一行没有以行终止符结束,则缓冲区不会在最终\n
之前以\0
结束,在所有其他情况下,它将
删除换行符的简单方法是:
line[strcspn(line, "\n")] = '\0';
如果找到\n
,则会覆盖\0
,否则会用\0
覆盖fgets()
。
请注意,您应该测试NULL
的返回值,如果它无法读取文件末尾的行,则返回for
。
另请注意,以这种方式编写for (i = 0; i < j; i++) { ... }
循环更简单,更惯用:
0
索引j
将被包含在内,索引qsort
将不会出现,这与您的语法相同,但更简单易读。
您还可以使用main()
使用3种不同的比较函数对表格进行排序。
另请注意,您对int main(void)
的定义已过时且不适用于C99及更高版本的C标准。您应该写int main(int argc, char *argv[])
或p
。
以下是问题列表:
long int
定义为%d
,但使用sscanf
通过printf
阅读并使用%ld
打印,正确格式为{{ 1}}。struct census
,这是不正确的,sortm_city
确实不返回任何内容,它们应定义为void
。header
应声明并定义为void header(void)
main
应定义为int main(void)
scanf_s
和sscanf_s
。 Visual Studio可能推荐使用这些函数,但scanf
和sscanf
并非总能在其他系统上使用这些函数,并且可以安全地使用这些函数并采取一些预防措施,尤其是%s
和{%[
{1}}格式,无论如何你都不会在这里使用。fgets
将\n
留在行尾。您应该检查retuen值以检测文件的过早结束并去除\n
。我定义了一个实用程序函数xgets()
。 strcspn()
返回其字符串参数中的字符数,这些字符不在作为第二个字符串参数给出的列表中。%f
作为识字级别,产生6个小数位(默认值),您应该使用%7.2f
获得2个小数位并对齐列内容。%%
打印%
printf
字符。printf
格式字符串中添加了一些对齐参数以对齐输出,假设使用固定宽度字体:"| %-15s | %10ld | %7.2f%% |"
。 %-15s
将城市名称填充为15个字符,并在城市名称之后填充空格,%10ld
将人口填充为10个字符,空格之前人口数字。 %7.2f
生成2个小数位,并且在.
之前的识字数字最多为7个字符之前用空格填充。qsort
并为3个排序选项定义了3个比较函数。以下是更正后的简化版本:
#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 a line from the user */
if (!fgets(dest, size, fp)) {
/* read failed, end of file detected */
printf("Premature end of file\n");
exit(1);
}
/* strip the \n if present */
dest[strcspn(dest, "\n")] = '\0';
return dest;
}
//PROGRAM STARTS HERE
int main(void) {
//VARIABLE-DECLARATION
int i = 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 and Literacy level");
printf("\n\n");
for (i = 0; i < j; i++) {
printf("City No. %d - Info :", i + 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");
for (i = 0; i < j; i++) {
printf("City No. %d - Info :", i + 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 one option from the following : \n\n");
printf("(a) To Sort the List Alphabetically. \n");
printf("(b) To Sort the List based on Literacy Level. \n");
printf("(c) To Sort the List based on Population. \n\n");
printf("Please type a 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 a 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");
for (i = 0; i < 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 by 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");
}