尝试在我的程序的字符串数组中输入多个字符串,用于:
scanf("%80[^\r\n]", strings[i]);
fgets(string[i], MAXLEN, stdin);
还使用了自定义功能:
int getString(char s[]) {
char ch;
int i=0;
while( (ch = getchar()) != '\n' && ch != EOF ) {
s[i] = ch;
++i;
}
s[i] = '\0';
fflush(stdin);
return i;
}
但无法输入多个字符串,每个字符串包含空格
函数gets()
过去对我来说比较早,但由于它已被弃用,因此无法找到替代方案
这是使用它的地方:
int getString(char s[]) {
char ch;
int i=0;
while( (ch = getchar()) != '\n' && ch != EOF ) {
s[i] = ch;
++i;
}
s[i] = '\0';
fflush(stdin);
return i;
}
struct vechileData
{
char vechileType[MAXLEN];
int begin_month;
int end_month;
double price;
} data[5];
int main(int argc, char const *argv[])
{
printf("Input Vechile data: \n");
int i=0;
while(i < 5) {
printf("Input vechile Type : \n");
fgets(data[i].vechileType, MAXLEN, stdin);
printf("Input begin month : \n");
scanf("%d", &data[i].begin_month);
printf("Input end monhth : \n");
scanf("%d", &data[i].end_month);
printf("Input price : \n");
scanf("%lf", &data[i].price);
++i;
}
printf("Input Vechile Type to display information about the vechile : \n");
char vech[MAXLEN];
fgets(vech, MAXLEN, stdin);
i=0;
while(i < 5) {
if (strcmp(vech,data[i].vechileType) == 0)
{
printf("vechileType: %s\n", data[i].vechileType);
printf("Begin month: %d\n", data[i].begin_month);
printf("End month: %d\n", data[i].end_month);
printf("Price : %lf\n", data[i].price);
}
++i;
}
return 0;
}
它在运行时跳过下一个字符串语句输入,“似乎”
答案 0 :(得分:5)
您的问题确实不是gets()
问题。
scanf("%d", ...)
和scanf("%lf", ...)
都没有消耗该号码后的'\n'
,从而导致您的问题。这是stdin
的下一次读取'\n'
。因此,当读取下一个车型时,它会得到延迟'\n'
。您的第二种车型最终为"\n"
。
使用fgets(data[i].vechileType, MAXLEN, stdin);
会在'\n'
中加data[i].vechileType
。你可能不想要这个。您之前使用gets()
消耗了,但没有将'\n'
放回其中。
由于这些微妙的问题,我很久以前放弃了使用scanf()
进行用户输入。
建议将输入与解析分开,使用fgets()
然后sscanf()
。例如:
char number[80];
if (fgets(number, sizeof(number), stdin)) {
sscanf(number, "%d", &x)
gets()
替换的实现方式如下:
1)它不返回s
(或NULL或错误/ eof)
2)它没有在eof上设置eof指示符。
3)如果getchar()
返回'\0'
,您的while
循环会错误地继续。
建议如果您必须替换gets()
,请通过fgets()
执行此操作。
#define My_gets_N (1024 /* Some BA number */)
char *My_gets(char * str) {
char buffer[My_gets_N];
char *retval = fgets(buffer, sizeof(My_gets_N), stdin);
if (retval) {
int l = strlen(buffer);
/* fgets() saves '\n', but gets() does not */
if ((l > 0) && (buffer[l-1] == '\n')) {
l--;
}
memcpy(str, buffer, l);
str[l] = '\0';
return str;
}
else {
return 0;
}
}
如果替换解决方案需要处理字符串长度&gt;固定My_gets_N
,需要其他编码。
答案 1 :(得分:2)
你必须更加具体地了解fgets()
方法出了什么问题,这是我推荐的方法,它确实有效。
请注意,fgets()
将输入整行,包括最后的换行符/回车符,因此如果不希望保留它们,您可能需要将其清除。
答案 2 :(得分:1)
我不明白gets()
是如何为你工作的,尽管K&amp; R几乎每个C书都给出了警告,因为它不仅被弃用,而且使用起来非常危险。就像其他人所说的那样,如果你正确使用它,fgets()
肯定会有用。
答案 3 :(得分:0)
而不是用gets
替换fgets
的所有使用实例。使用以下宏:
#define TRUNCATE_NULL(strText) \
{ \
int _strlen = strlen(strText); \
if (_strlen > 0 && strText[_strlen - 1] == '\n') strText[_strlen - 1] = '\0'; \
else while(fgetc(stdin)!='\n'); \
}
#define gets(strText) fgets(strText, sizeof(strText), stdin); TRUNCATE_NULL(strText);
为什么要使用fgets
?
因为它比gets
更安全。
gets
真的不安全吗?
是。它确实是贪婪的,它会接受尽可能多的食物,即使它不能吃
从技术上讲,正如@halfer在下面正确评论的那样,
使用gets,程序容易出现缓冲区溢出。
怎么样?
char name[5];
gets(name);
现在提供超过5个字符的输入,它会接受它。
这会覆盖内存中的数据,不应该以这种方式覆盖。
好的fgets
,但为什么要使用TRUNCATE_NULL宏?
fgets
也不完美。它将接受\n
(回车)作为要放入输入名称的字符。
因此,为了删除不必要的\n
,并确保实现gets
的预期功能,我们可以使用它。
答案 4 :(得分:0)
实际上,你可以使用while((getchar())!='\n');
来避免这种类型的问题,有一件事就是不需要使用fflush(stdin)函数。
这是您可以使用的代码
#include<stdio.h>
#include<string.h>
#define MAXLEN 50
int getString(char s[])
{
char ch;
int i=0;
while( (ch = getchar()) != '\n' && ch != EOF )
{
s[i] = ch;
++i;
}
s[i] = '\0';
return i;
}
struct vechileData
{
char vechileType[MAXLEN];
int begin_month;
int end_month;
double price;
}data[5];
int main(int argc, char const *argv[])
{
printf("Input Vechile data: \n");
int i=0;
while(i < 2)
{
printf("Input vechile Type : \n");
fgets(data[i].vechileType, MAXLEN, stdin);
printf("Input begin month : \n");
scanf("%d", &data[i].begin_month);
printf("Input end monhth : \n");
scanf("%d", &data[i].end_month);
printf("Input price : \n");
scanf("%lf", &data[i].price);
while((getchar())!='\n');
++i;
}
printf("Input Vechile Type to display information about the vechile : \n");
char vech[MAXLEN];
fgets(vech, MAXLEN, stdin);
i=0;
while(i < 2)
{
if (strcmp(vech,data[i].vechileType) == 0)
{
printf("vechileType: %s\n", data[i].vechileType);
printf("Begin month: %d\n", data[i].begin_month);
printf("End month: %d\n", data[i].end_month);
printf("Price : %lf\n", data[i].price);
}
++i;
}
return 0;
}
我希望这会对你有帮助.....