c语言怎么输入一个字符串跳出循环,关于字符串:键入Quit退出C程序
我在想程序的问题是什么。 键入quit时无法退出程序。
这是我所拥有的:
#include
#include
int main(void) {
char string[200];
printf("Enter a bunch of words:");
do
{
scanf("%[^
]c", string);
}while(strcmp(string,"quit")!=0);
return 0;
}
scanf(" %199[^
]", string);注意%和199之前的空格,以防止写入string的字符过多。不需要尾随c
您是否对使用scanf进行的锻炼有规范要求?如果不是,则ID建议其他方法。
@GovindParmar是的,我必须使用scanf,我们不能使用我们尚未学习的任何东西。
@UnholySheep不,它不是。它是一种字符串的扫描格式,该字符串包含除换行符之外的任何字符,后跟文字c。
为什么使用scanf("%[^
]c", string);而不是fgets (string, sizeof string, stdin)? (然后是strncmp (string,"quit", 4);)
@ DavidC.Rankin这是学校作业的一部分,我不能使用任何尚未教过的东西,所以我必须使用scanf
那scanf(" %[^
]%*c", string);呢? (*是分配抑制运算符,允许在不影响返回的转换计数的情况下读取和忽略下一个字符(例如%c)。(应检查if (scanf(" %[^
]%*c", string) != 1) { * handle error * })
嗨@anon您应该解释您认为"%[^
]c"的含义。
@AnttiHaapala:并不是真的。 %[^
]将留在输入流中。因此,下一个字符不能为文字c。
@ DavidC.Rankin hmmm,非常感谢您提供此修复程序,非常感谢,但是我仍然没有被教过这种技术,因此我必须以一种更简单的方式来做。有没有办法做while(1)然后在循环内做if(strcmp(string," quit")!= 0)break;香港专业教育学院尝试了这么多的排列,我不知道如何使它工作。
@jxh当然不可能匹配整个格式,但这就是什么意思。
@jxh它在单词之间留有空格。我想,如果我没有它,它将停在第一个空间。
@anon:但是,您想用尾随的c完成什么?
您的两个最大问题是使用scanf困扰新C程序员的两个最常见问题:
You are using an incorrect format string; and
You fail to check the return of scanf.
让我们首先解决第一件事:
scanf("%[^
]c", string);
您的格式字符串"%[^
]c"使用字符类格式说明符"%[...]"来读取string的文本。然后是"c" -仅与输入字符串末尾的文字'c'相匹配。那样写不会发生,因为"%[^
]"将读取不是'
'的所有字符,仅保留'
'才能读取-与'c'不匹配。
此外,"%[...]"说明符与"%c"说明符一起不占用前导空格('
'为空格)。因此,在stdin中保留未读取的'
'时,您对下一个scanf的调用将失败,因为"%[^
]"不会读取'
'并且它与'c'不匹配,从而导致匹配失败,即'
'在stdin中仍然未被读取,事情很快就失控了。
要解决所有问题,您需要记住上面的(2.)并使用字段宽度修饰符来保护string的数组边界,然后您应读取并保存提取并放入string的字符后的字符以验证是否已读取完整的输入行-否则,您有责任在尝试下一次读取之前删除stdin中剩余的所有多余字符。
对于初学者,您可以使用格式适当受限的字符串,该字符串开头应包含space,这将导致scanf放弃所有前导空格,例如
" %199[^
]%c"
请注意,上面的最终字符将被保存,将进行两次转换,因此您将需要一个字符变量来处理最终转换说明符的结果,例如
do {
char c; /* final character read */
int retn; /* variable to save scanf return */
/* prompt */
fputs ("Enter a bunch of words ('quit' exits):", stdout);
/* read saving scanf return */
retn = scanf (" %199[^
]%c", string, &c);
(注意:提示已在do {...} while (..);循环内移动)
接下来,您将负责每次检查scanf的返回。您必须处理三个条件
(return == EOF)用户通过按Ctrl + d(或在Windows Ctrl + z上)生成手册EOF来取消输入;
(return < expected No. of conversions),必须处理匹配或输入失败,并且必须考虑输入缓冲区中可能剩余的每个字符。 (通常,您将在输入缓冲区中向前扫描,直到找到'
'或EOF并丢弃其余的多余字符,请参见示例中的empty_stdin()函数);和
(return == expected No. of conversions)表示读取成功-然后由您检查输入是否满足任何其他条件(例如正整数,正浮点等)。
综上所述,您可以使用scanf循环阅读并寻找"quit"作为提示退出的关键字,如下所示:
do {
char c; /* final character read */
int retn; /* variable to save scanf return */
/* prompt */
fputs ("Enter a bunch of words ('quit' exits):", stdout);
/* read saving scanf return */
retn = scanf (" %199[^
]%c", string, &c);
if (retn == EOF) { /* check the return against EOF */
fputs ("(user canceled input)
", stderr);
return 0;
}
else if (retn < 2) { /* checking both string and c read */
fputs ("input failure.
", stderr);
empty_stdin();
}
else if (c != '
') { /* check c is '
', else string too long */
fprintf (stderr,"warning: input exceeds %d characters.
",
MAXC - 1);
empty_stdin();
}
else /* good input, output string */
printf ("string: %s
", string);
} while (strcmp (string,"quit") != 0);
最后,请勿在代码中使用幻数(200是幻数)。相反,如果您需要一个常数,则#define一个(或多个)。您必须对数字进行硬编码的唯一地方是例如scanf field-width修饰符-不能使用变量,宏或命名常量。这是该规则的一个例外。同样,请勿对文件名或路径进行硬编码。所有函数都带有参数,甚至main()都将所需的信息传递给程序。
综上所述,您可以执行以下操作:
#include
#include
#define MAXC 200 /* constant - maximum characters in string */
void empty_stdin (void)
{
int c = getchar();
while (c != EOF && c != '
')
c = getchar();
}
int main (void) {
char string[MAXC]; /* use constants for array bounds */
do {
char c; /* final character read */
int retn; /* variable to save scanf return */
/* prompt */
fputs ("Enter a bunch of words ('quit' exits):", stdout);
/* read saving scanf return */
retn = scanf (" %199[^
]%c", string, &c);
if (retn == EOF) { /* check the return against EOF */
fputs ("(user canceled input)
", stderr);
return 0;
}
else if (retn < 2) { /* checking both string and c read */
fputs ("input failure.
", stderr);
empty_stdin();
}
else if (c != '
') { /* check c is '
', else string too long */
fprintf (stderr,"warning: input exceeds %d characters.
",
MAXC - 1);
empty_stdin();
}
else /* good input, output string */
printf ("string: %s
", string);
} while (strcmp (string,"quit") != 0);
return 0;
}
使用/输出示例
$ ./bin/scanf_string_quit
Enter a bunch of words ('quit' exits): Hello
string: Hello
Enter a bunch of words ('quit' exits): My dog has fleas and my cat has none.
string: My dog has fleas and my cat has none.
Enter a bunch of words ('quit' exits): quit
string: quit
使用Ctrl + d(或在windoze上为Ctrl + z)生成手册EOF:
$ ./bin/scanf_string_quit
Enter a bunch of words ('quit' exits): Hello
string: Hello
Enter a bunch of words ('quit' exits): (user canceled input)
将MAXC重置为20并将字段宽度修饰符重置为scanf到19,您可以检查对太长的行的处理,例如第一个输入合适,第二个输入太长:
$ ./bin/scanf_string_quit
Enter a bunch of words ('quit' exits): my dog has fleas and my cat has none.
warning: input exceeds 19 characters.
Enter a bunch of words ('quit' exits): 1234567890123456789
string: 1234567890123456789
Enter a bunch of words ('quit' exits): 12345678901234567890
warning: input exceeds 19 characters.
Enter a bunch of words ('quit' exits): quit
string: quit
仔细检查一下,如果您还有其他问题,请告诉我。
哇!非常感谢,我非常感谢所有细节。 Ive遵循了您和另一个用户的建议,一旦我键入quit,程序就会退出。但是,这导致了一个新问题,因为我没有描述程序的目的,所以你们回答了您认为程序想要的内容,我将发布一个新问题,更全面地解释我拥有程序后想要做什么放弃。
这样的事情可以接受吗?
#include
#include
int main(void) {
char string[200] = {0};
printf("Enter a bunch of words:");
do {
memset(string, 0, 200);
scanf("%s", string);
} while (strcmp(string,"quit") != 0);
return 0;
}
您尚未确切说明要对字符串进行的处理,因此很难给出答案。但是,要注意的一件事是,您必须对string做一些事情(我刚刚在这里将其归零),以便strcmp识别"退出",或者扫描string的子字符串,因为如果所有内容都会附加在后面,然后您的字符串将是"(...)quit",而strcmp不会将其识别为" quit"。
附带说明一下,请始终初始化数组,否则可能会发生不良情况。
我不能使用memset,我还没在课堂上学到:/。但是,我按照您的建议初始化了数组,并且无需memset即可工作。非常感谢!
@anon您也可以使用for循环将string中的每个索引设置为0,但是任务可能不仅仅需要这样做。很高兴这是有用的。
@Joshua我一直都喜欢Integer Overflow Man,他是我最喜欢的超级英雄。确实存在这种危险,但是匿名人士并没有真正指定他所完成任务的界限,所以我只是想提出最简单的建议,以解决他似乎遇到的问题。内存安全似乎并不是其中的一部分。
鉴于您提供的稀疏解释,最直接的更改可能是修改扫描字符串以吞下而不是理论上的c,这实际上是不可能的:
scanf("%[^
]
", string);
为了防止缓冲区溢出,您应该指定缓冲区必须存储多少空间:
scanf("%199[^
]
", string);
只要您知道输入内容永远不会超过199个字符,这是安全的。但这在理论和实践上都是一个很弱的假设。超过199的字符将在下一次迭代中作为下一个单词被扫描,如果输入的是199 .后跟单词quit,则程序将意外退出。您需要一种更可靠的方法来扫描到该行的其余部分并丢弃它,然后再读取下一行。
您可能会想使用另一个%[...]来捕获额外的字符,如下所示:
scanf("%199[^
]%*[^
]
", string);
但是,对于输入少于或等于199个字符的常见情况,这将失败。这是因为如果转换导致输入为空,则scanf将失败。因此,将保留在输入中。
如果限于使用scanf,则需要将扫描分为多个单独的scanf调用,以便将其余行的错误和非错误扫描视为相同的结果,从而导致第二个scanf吞下换行符本身。
scanf("%199[^
]%*[^
]", string);
scanf("
");
c语言怎么输入一个字符串跳出循环,关于字符串:键入Quit退出C程序相关推荐
- c语言输入一段字符,C语言实现输入一个字符串后打印出该字符串中字符的所有排列...
本文实例讲述了C语言实现输入一个字符串后打印出该字符串中字符的所有排列的方法,属于数学里的排列问题.是一个很实用的算法技巧.分享给大家供大家参考.具体实现方法如下: 例如输入字符串abc,则输出由字符 ...
- C语言如何输入一个字符串?
C语言如何输入一个字符串? 用scanf输入字符串(有限制) 整个字符串处理 逐个字符处理 用getchar()输入字符串 用gets()输入字符串(简单快捷) gets函数与scanf.getcha ...
- C# 输入一个三位数的字符串,输出为三位数的整数,并输出百位、十位、和个位
C# 输入一个三位数的字符串,输出为三位数的整数,并输出百位.十位.和个位 以C# 语言编写,控制台应用程序运行 文章目录 C# 输入一个三位数的字符串,输出为三位数的整数,并输出百位.十位.和个位 ...
- C语言如何编程换算小时秒,c语言编写 输入一个以秒为单位的时间值,将其转化成“时:分:秒”的形式输出,将转换操作定义成函式...
c语言编写 输入一个以秒为单位的时间值,将其转化成"时:分:秒"的形式输出,将转换操作定义成函式以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整 ...
- java中如何输入一个字符(用字符串转换)
java中的Scanner类中并没有包括单独输入char型字符的情况,但是我们可以通过输入一个长度仅为1的字符串,然后将字符串转换为char型字符,再用新的char型变量接收就好了. java源文件名 ...
- c语言:输入一个四位数字,每两个数字简空一格
c语言:输入一个四位数字,每两个数字简空一格 #include<stdio.h> #include<stdlib.h> #include<string.h> #in ...
- c语言案例——输入一个字符串,将其逆序输出
字符串常量可以赋值给一个字符指针或者一个字符数组,比如: /*1*/char *str = "this is a string"; /*2*/char str2[]= " ...
- C语言:从键盘输入一个长度不定的字符串[C_004]
目录 背景: Solution: 方案一:那就不要字符串 方案二:动态申请内存 背景: 在很多时候,会遇到从外部按要求输入字符串的情形,有些是明确了长度,有些只是给定了最大长度,而有些没有规定长度.对 ...
- 【c语言】输入一个4位数,求四位数中各位数相加之和
<程序设计基础实训指导教程-c语言>杨莉 龚义建 科学出版社 ISBN 978-7-03-032846-5 p9 2.1.2 上机实训内容 [实训内容1] 编程实现:输入一个4位数,求4位 ...
最新文章
- catch里面不想做任何处理_Java 如何优雅处理 Exception? 看完这 9 个示例你秒懂
- 【转】6 Reasons Why JavaScript’s Async/Await Blows Promises Away (Tutorial)
- 左神算法:反转单向和双向链表(Java版)
- superset可视化-word cloud
- 计算信源熵和香农编码C语言,信息论与编码课程设计报告-统计信源熵与香农编码.pdf...
- 卡尔曼滤波、扩展卡尔曼滤波、无迹卡尔曼滤波以及粒子滤波原理
- Virtual DOM(虚拟dom-1)
- CDays–5 习题二(利用Python科学计算特性,使用常用计算符)及相关内容解析。...
- Spark性能优化:Shuffle调优篇
- 最简单的Qt配置opencv教程
- php uploadify下载,JQuery上传插件Uploadify的下载与讲解
- java常用工具下载
- Trajectory Similarity Join in Spatial Networks
- 杨氏不等式(控制中的应用)
- Visual C++不小心卸载,很多软件不能用了怎么办
- Java EE Security API ,给企业最棒的安全守护!
- java基础案例3-2银行存取款
- 气动和液压的差异点,可能会颠覆你的认知哦!
- oracle apex接口文件,Oracle Apex 实用笔记系列 2 - 文件上传管理
- 当数据分析遭遇心理动力学:用户深层次的情感需求浮出水面(万字长文,附实例分析)...