3

尝试在我的程序的字符串数组中输入多个字符串,用于:

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;
}

它在运行时跳过字符串语句的下一个输入,“似乎”

4

5 回答 5

7

你的问题真的不是gets()问题。

没有scanf("%d", ...)scanf("%lf", ...)消耗'\n'数字后的数字,从而导致您的问题。这是下一个阅读stdin的内容'\n'。因此,当读取下一个汽车类型时,它得到了挥之不去的'\n'. 您的第 2 种汽车类型最终是"\n".

使用fgets(data[i].vechileType, MAXLEN, stdin);puts a '\n'in data[i].vechileType。你可能不想要这个。你以前使用gets()消耗,但没有把'\n'它归还。

scanf()由于这些微妙的问题,我很久以前就放弃了用户输入。建议将输入与解析分开,使用fgets()then sscanf()。例子:

char number[80];
if (fgets(number, sizeof(number), stdin)) {
  sscanf(number, "%d", &x)

您的gets()替换实现如下所示

1) 它不返回s(或 NULL 或错误/eof)。
2) 它没有在 eof 上设置 eof 指示符。3)应该getchar()返回 a '\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;
  }
}

如果您的替换解决方案需要处理字符串长度 > 固定My_gets_N,则需要其他编码。

于 2013-06-05T15:04:01.060 回答
2

您必须更具体地说明该方法出了什么问题fgets(),这是我推荐的方法,它确实有效。

请注意,这fgets()将输入整行,包括最后的换行符/回车符,因此如果不希望保留它们,您可能需要清除它们。

于 2013-06-05T12:11:52.790 回答
1

我不明白你是如何gets()工作的,尽管几乎每一篇 C 书籍帖子 K&R 都给出了警告,因为它不仅被弃用,而且使用起来非常危险。就像其他人说的fgets()那样,如果你正确使用它肯定会起作用。

于 2013-06-05T12:15:01.587 回答
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);
  1. 为什么使用fgets

    因为它比gets.

  2. 真的gets没有安全感吗?

    是的。它确实很贪婪,它会接受你给的多少食物,即使它不能吃。
    所以从技术上讲,正如@halfer 在下面正确评论
    的那样,使用gets,程序很容易出现缓冲区溢出

  3. 如何 ?

    char name[5];
    gets(name);
    

    现在提供超过 5 个字符的输入,它将接受它。
    这将覆盖内存中的数据,不应以这种方式覆盖。

  4. 好的fgets,但为什么要使用 TRUNCATE_NULL 宏?

    fgets也不完美。它将接受\n(Enter) 作为要放置在输入名称中的字符。
    因此,要删除不必要\n的 ,并确保gets实现预期的功能,我们可以使用它。

于 2016-12-15T19:02:50.430 回答
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;
}

我希望这能帮到您.....

于 2017-04-02T09:36:08.787 回答