如果我使用fputs/fgets,C程序在if/else之后终止或重复
我对C非常陌生,涉足过Objective-C、AppleScript和HTML/CSS。我确信我的问题很容易解决。我正在尝试写一些东西,允许我输入源数据,并以某种方式将其排序为输出(在本例中为引用)。基本上,我希望将名称、标题、发布者等保存为变量,并按一定顺序打印它们 问题是:这里的代码终止得太早,当我将fput和fgets与stdout和stdin一起使用时,它会被卡住,永远问同样的问题。我错过了什么如果我使用fputs/fgets,C程序在if/else之后终止或重复,c,stdin,scanf,fgets,fputs,C,Stdin,Scanf,Fgets,Fputs,我对C非常陌生,涉足过Objective-C、AppleScript和HTML/CSS。我确信我的问题很容易解决。我正在尝试写一些东西,允许我输入源数据,并以某种方式将其排序为输出(在本例中为引用)。基本上,我希望将名称、标题、发布者等保存为变量,并按一定顺序打印它们 问题是:这里的代码终止得太早,当我将fput和fgets与stdout和stdin一起使用时,它会被卡住,永远问同样的问题。我错过了什么 int source_type; int NumberofAuthors; char Aut
int source_type;
int NumberofAuthors;
char AuthorName1[20];
char AuthorName2[20];
char AuthorName3[20];
char title[20];
char url[100];
char publishingCity[20];
char publisher[20];
char yearPublished[20];
char pageNumbers[20];
int valid;
printf("Welcome to Jackson's Chicago Manual of Style Auto-Footnoter.\n");
fputs("Choose source type:\n a.Book\n b.Journal\n c.Article\n d.Website\n ", stdout);
source_type = getchar();
if (source_type == 'a') {
valid = 1;
} else {
printf("Invalid source selection");
}
while ( valid == 1 && source_type == 'a' )
{
printf("Number of authors [1 or 2]: ");
scanf( "%d", &NumberofAuthors);
if ( NumberofAuthors > 0 && NumberofAuthors < 3 ) {
valid = 1;
printf("Got it, %d author(s).\n", NumberofAuthors);
}
else {
printf( "That's not enough people to write a book.\n" );
}
if ( NumberofAuthors == 1 ) {
printf( "Author's name: " );
scanf("%c", &AuthorName1);
}
if (NumberofAuthors == 2) {
printf("First author's name: " );
scanf("%c", &AuthorName2);
printf("Second author's name: " );
scanf("%c", &AuthorName3);
}
else {
valid = 0;
}
printf("Book title: " );
fgets(title, sizeof(title), stdin);
printf("Publication city: " );
fgets(publishingCity, sizeof(publishingCity), stdin);
}
return 0;
int源代码类型;
作者人数;
char AuthorName1[20];
char AuthorName2[20];
char AuthorName3[20];
字符标题[20];
charurl[100];
煤焦出版城[20];
字符发布器[20];
已出版[20];
字符页码[20];
int有效;
printf(“欢迎来到杰克逊的芝加哥风格手册自动脚注。\n”);
fputs(“选择源类型:\n a.Book\n b.Journal\n c.Article\n d.Website\n”,标准输出);
source_type=getchar();
如果(源类型=='a'){
有效=1;
}否则{
printf(“无效源选择”);
}
while(valid==1&&source\u type==a)
{
printf(“作者数量[1或2]:”;
scanf(“%d”和NumberofAuthors);
if(NumberofAuthors>0&&NumberofAuthors<3){
有效=1;
printf(“得到它,%d个作者)。\n”,NumberofAuthors);
}
否则{
printf(“没有足够的人来写一本书。\n”);
}
如果(NumberofAuthors==1){
printf(“作者姓名:”);
scanf(“%c”和AuthorName1);
}
如果(NumberofAuthors==2){
printf(“第一作者姓名:”);
scanf(“%c”和AuthorName2);
printf(“第二作者姓名:”);
scanf(“%c”和AuthorName3);
}
否则{
有效=0;
}
printf(“书名:”);
fgets(标题、尺寸(标题)、标准DIN);
printf(“出版城市:”);
fgets(出版城市)、sizeof(出版城市)、stdin;
}
返回0;
在循环时,您只会在之外更改源类型
,因此一旦进入循环,唯一的退出方法就是将0
分配给有效的
。每次NumberofAuthors!=2
,因为第一个if
不在if-else
链中。也许你想要这个:
if ( NumberofAuthors == 1 ) {
printf( "Author's name: " );
scanf("%c", &AuthorName1);
} else if (NumberofAuthors == 2) {
printf("First author's name: " );
scanf("%c", &AuthorName2);
printf("Second author's name: " );
scanf("%c", &AuthorName3);
} else {
valid = 0;
}
关于该计划的实施:
if (source_type == 'a') {
valid = 1;
} else {
printf("Invalid source selection");
}
如果source\u type
无效,valid
仍然包含垃圾值,使用未初始化的变量是未定义的行为。继续
while ( valid == 1 && source_type == 'a' )
{
printf("Number of authors [1 or 2]: ");
scanf( "%d", &NumberofAuthors);
if ( NumberofAuthors > 0 && NumberofAuthors < 3 ) {
valid = 1;
printf("Got it, %d author(s).\n", NumberofAuthors);
}
//...
我希望您意识到,在NumberofAuthors==1
的情况下,else
部分将执行并设置valid=0
。这是因为else只会在最近的if上粘住,而且仅此而已
我猜您使用FGET等来避免溢出。好。查看scanf
s上的技巧。请在此处阅读更多信息:
试试看:
int main(int argc, char* argv[])
{
char source_type;
int NumberofAuthors;
char AuthorName1[20];
char AuthorName2[20];
char AuthorName3[20];
char title[20];
char url[100];
char publishingCity[20];
char publisher[20];
char yearPublished[20];
char pageNumbers[20];
int valid;
printf("Welcome to Jackson's Chicago Manual of Style Auto-Footnoter.\n");
printf("Choose source type:\n a.Book");
scanf("%c" , &source_type);
if (source_type == 'a') {
valid = 1;
} else {
printf("Invalid source selection");
valid = 0;
}
while ( valid == 1 && source_type == 'a' )
{
//Reset
valid = 0;
printf("Number of authors [1 or 2]: ");
scanf( "%d", &NumberofAuthors);
if ( NumberofAuthors > 0 && NumberofAuthors < 3 ) {
valid = 1;
printf("Got it, %d author(s).\n", NumberofAuthors);
}
else {
printf( "That's not enough people to write a book.\n" );
continue;
}
switch( NumberofAuthors )
{
case 1:
printf( "Author's name: " );
scanf("%19s", AuthorName1);
break;
case 2:
printf("First author's name: " );
scanf("%19s", AuthorName2);
printf("Second author's name: " );
scanf("%19s", AuthorName3);
break;
default:
valid = 0;
break;
}
if(valid)
{
printf("Book title: " );
scanf("%19s" , title);
printf("Publication city: " );
scanf("%19s" , publishingCity );
}
}
return 0;
}
intmain(intargc,char*argv[])
{
字符源类型;
作者人数;
char AuthorName1[20];
char AuthorName2[20];
char AuthorName3[20];
字符标题[20];
charurl[100];
煤焦出版城[20];
字符发布器[20];
已出版[20];
字符页码[20];
int有效;
printf(“欢迎来到杰克逊的芝加哥风格手册自动脚注。\n”);
printf(“选择源类型:\n a.Book”);
scanf(“%c”和源类型);
如果(源类型=='a'){
有效=1;
}否则{
printf(“无效源选择”);
有效=0;
}
while(valid==1&&source\u type==a)
{
//重置
有效=0;
printf(“作者数量[1或2]:”;
scanf(“%d”和NumberofAuthors);
if(NumberofAuthors>0&&NumberofAuthors<3){
有效=1;
printf(“得到它,%d个作者)。\n”,NumberofAuthors);
}
否则{
printf(“没有足够的人来写一本书。\n”);
继续;
}
开关(NumberofAuthors)
{
案例1:
printf(“作者姓名:”);
scanf(“%19s”,AuthorName1);
打破
案例2:
printf(“第一作者姓名:”);
scanf(“%19s”,AuthorName2);
printf(“第二作者姓名:”);
scanf(“%19s”,AuthorName3);
打破
违约:
有效=0;
打破
}
如果(有效)
{
printf(“书名:”);
scanf(“%19s”,标题);
printf(“出版城市:”);
scanf(“%19s”,出版城市);
}
}
返回0;
}
您正在使用%c
读取姓名;这不好。传递的是数组的地址,而不是指向数组第一个元素的指针;这也不好。你到处践踏,给自己留下了未定义的行为问题
“明显的”修复方法是使用%s
并在数组名称前面放弃&
,但您不能屈从于明显的,因为它是错误的。大多数作者的名字和姓氏(或首字母和姓氏)之间有空格,%s
在第一个空格处停止。您需要使用fgets()
读取名称,但请记住删除尾随的换行符
我不太清楚为什么“AuthorName1”中只有一个作者的名字,而“AuthorName2”和“AuthorName3”中有两个作者;不管怎样,我都希望第一作者使用“名字1”。事实上,最好有一组作者姓名——这样更容易概括
当我编译代码(将其包装在intmain(void){
和}
中并包含
时,我会收到编译警告:
xx.c: In function ‘main’:
xx.c:43: warning: format ‘%c’ expects type ‘char *’, but argument 2 has type ‘char (*)[20]’
xx.c:43: warning: format ‘%c’ expects type ‘char *’, but argument 2 has type ‘char (*)[20]’
xx.c:48: warning: format ‘%c’ expects type ‘char *’, but argument 2 has type ‘char (*)[20]’
xx.c:48: warning: format ‘%c’ expects type ‘char *’, but argument 2 has type ‘char (*)[20]’
xx.c:50: warning: format ‘%c’ expects type ‘char *’, but argument 2 has type ‘char (*)[20]’
xx.c:50: warning: format ‘%c’ expects type ‘char *’, but argument 2 has type ‘char (*)[20]’
我重写了代码,使用一个函数来处理字符串的提示和读取,因此:
#include <assert.h>
#include <stdio.h>
#include <string.h>
static int get_string(const char *prompt, char *buffer, size_t bufsiz)
{
char *nl;
printf("%s: ", prompt);
fflush(0);
if (fgets(buffer, bufsiz, stdin) == 0)
return EOF; /* Read error - EOF */
if ((nl = strchr(buffer, '\n')) == 0)
{
fprintf(stderr, "Overlong string entered!\n");
return EOF;
}
*nl = '\0';
return 0;
}
int main(void)
{
int source_type;
int NumberofAuthors;
char AuthorName1[20];
char AuthorName2[20];
char title[20];
char publishingCity[20];
int valid = 0;
int c;
printf("Welcome to Jackson's Chicago Manual of Style Auto-Footnoter.\n");
fputs("Choose source type:\n a.Book\n b.Journal\n c.Article\n d.Website\n ", stdout);
source_type = getchar();
if (source_type == 'a')
valid = 1;
else
{
printf("Invalid source selection");
return(1);
}
/* Lucky that scanf() skips over the newline in search of digits! */
while (valid == 1 && source_type == 'a')
{
printf("Number of authors [1 or 2]");
scanf("%d", &NumberofAuthors);
if (NumberofAuthors > 0 && NumberofAuthors < 3)
{
valid = 1;
printf("Got it, %d author(s).\n", NumberofAuthors);
}
else
{
printf("That's not enough (or too many) people to write a book.\n");
break;
}
/* Gobble to newline */
while ((c = getchar()) != EOF && c != '\n')
;
if (NumberofAuthors == 1)
{
if (get_string("Author's name", AuthorName1, sizeof(AuthorName1)) == EOF)
{
valid = 0;
break;
}
}
else
{
assert(NumberofAuthors == 2);
if (get_string("First author's name", AuthorName1, sizeof(AuthorName1)) == EOF ||
get_string("Second author's name", AuthorName2, sizeof(AuthorName2)) == EOF)
{
valid = 0;
break;
}
}
if (get_string("Book title", title, sizeof(title)) == EOF ||
get_string("Publication city", publishingCity, sizeof(publishingCity)) == EOF)
{
valid = 0;
break;
}
printf("Author 1: %s\n", AuthorName1);
if (NumberofAuthors == 2)
printf("Author 2: %s\n", AuthorName2);
printf("Book title: %s\n", title);
printf("Publication city: %s\n", publishingCity);
}
return 0;
}
#包括
#包括
#包括
静态int get_字符串(const char*p
#include <assert.h>
#include <stdio.h>
#include <string.h>
static int get_string(const char *prompt, char *buffer, size_t bufsiz)
{
char *nl;
printf("%s: ", prompt);
fflush(0);
if (fgets(buffer, bufsiz, stdin) == 0)
return EOF; /* Read error - EOF */
if ((nl = strchr(buffer, '\n')) == 0)
{
fprintf(stderr, "Overlong string entered!\n");
return EOF;
}
*nl = '\0';
return 0;
}
int main(void)
{
int source_type;
int NumberofAuthors;
char AuthorName1[20];
char AuthorName2[20];
char title[20];
char publishingCity[20];
int valid = 0;
int c;
printf("Welcome to Jackson's Chicago Manual of Style Auto-Footnoter.\n");
fputs("Choose source type:\n a.Book\n b.Journal\n c.Article\n d.Website\n ", stdout);
source_type = getchar();
if (source_type == 'a')
valid = 1;
else
{
printf("Invalid source selection");
return(1);
}
/* Lucky that scanf() skips over the newline in search of digits! */
while (valid == 1 && source_type == 'a')
{
printf("Number of authors [1 or 2]");
scanf("%d", &NumberofAuthors);
if (NumberofAuthors > 0 && NumberofAuthors < 3)
{
valid = 1;
printf("Got it, %d author(s).\n", NumberofAuthors);
}
else
{
printf("That's not enough (or too many) people to write a book.\n");
break;
}
/* Gobble to newline */
while ((c = getchar()) != EOF && c != '\n')
;
if (NumberofAuthors == 1)
{
if (get_string("Author's name", AuthorName1, sizeof(AuthorName1)) == EOF)
{
valid = 0;
break;
}
}
else
{
assert(NumberofAuthors == 2);
if (get_string("First author's name", AuthorName1, sizeof(AuthorName1)) == EOF ||
get_string("Second author's name", AuthorName2, sizeof(AuthorName2)) == EOF)
{
valid = 0;
break;
}
}
if (get_string("Book title", title, sizeof(title)) == EOF ||
get_string("Publication city", publishingCity, sizeof(publishingCity)) == EOF)
{
valid = 0;
break;
}
printf("Author 1: %s\n", AuthorName1);
if (NumberofAuthors == 2)
printf("Author 2: %s\n", AuthorName2);
printf("Book title: %s\n", title);
printf("Publication city: %s\n", publishingCity);
}
return 0;
}