【问题标题】:Getting multiple strings as inputs获取多个字符串作为输入
【发布时间】:2017-07-04 17:54:17
【问题描述】:

问题是取三个名字作为输入,并检查第四个输入是否是这三个名字之一的第一个字母。 *它只需要是 alpha 类型,不能是其他类型。

示例输入:

@ON SNOW
ARYA STARK
HODOR
@ 

输出:

NO

我的代码:

#include <stdio.h>
#include <ctype.h>
int main(){
    char s1[100],s2[100],s3[100];
    char ch[1];
    scanf("%[^\n]s",s1);
    scanf("%[^\n]s",s2);
    scanf("%[^\n]s",s3);
    scanf("%s",ch);
    if(isalpha(ch[0]) && (s1[0]==ch[0] || s2[0]==ch[0] || s3[0]==ch[0]))
        printf("yes");
    else
        printf("no");
}

当我发现gets() 不再有效时,我尝试了scanf("%s",s1);。 但由于它没有在空格" " 之后存储计算,所以我尝试了这个scanf("%[^\n]s",s1);。但扫描停止在名字本身。

John Player
NO

不使用循环只使用分支的char数组中存储多个字符串的方法是什么??

【问题讨论】:

  • 试试"%[^\n]s" --> "%99[^\n]%*c"
  • @BLUEPIXY 你能解释一下这是什么意思吗?!是的..编码现在可以工作了!
  • 注意%[…]是一个扫描集,一个完整的转换规范。尾随的s 只会匹配文字s,但由于下一个字符是换行符,匹配将失败,但你永远不会知道。扫描集(以及%c%n——只有这三个转换说明符)不会跳过前导空格。在代码的开头(而不是结尾)添加一个空格。或者使用fgets() 来读取行——这可能会更好。
  • @Kraken 我相信 gets() 已从 stdio.h 作为 std 库函数中删除,因为会导致缓冲区溢出,并建议我们 fgets()。这些天你收到一条消息说:函数“gets”的隐式声明警告:“gets”函数很危险,不应该使用
  • 如果只教了基础知识,那么使用scanf() 和扫描集是不太可能教的;它不是scanf() 基础知识的一部分。使用fgets() 相对简单。并且结果通常比使用scanf() 等更可预测。

标签: c string char scanf


【解决方案1】:

现在在解决指定问题之前,让我们看看实际问题是什么:

  • scanf() 的问题

    scanf() 的问题在于它在管理溢出方面非常糟糕。如果是字符或字符序列,则在后续扫描中按回车键读取换行符。 SO上有很多涉及这个问题的实例。 scanf() leaves the new line char in buffer?Problems with scanf

  • gets() 的问题

    最大的缺点是这里你需要事先知道输入的大小。如果您非常了解自己的输入,则可以使用它(但我不推荐)。 Why is the gets function so dangerous that it should not be used?

  • fgets() 的问题

    fgets() 有两个非常常见的问题

    fgets() 的语法是:

          char *fgets(char *restrict s, int n, FILE *restrict stream);`
    

    和一般使用类似

          fgets(char_array,100,stdin)
    
    1. 当输入大于 fgets() 第二个参数中提供的整数 n 时,会出现第一个问题。当缓冲区中的输入大于 n 时,它将剥离第一个 n 字符并为其分配可能是 char 数组的 char 指针。但是剩下的字符呢?它们仍然在输入缓冲区中,并将分配给下一个 fgets()。搞砸了。

    2. 第二个问题是,当输入小于 int n-1 时,每次在 char 序列的末尾分配一个新的换行符。

但如果我们想一想 fgets() 的问题可以通过一个简单的技巧来解决。

  • 只需检查最近分配的字符序列中的最后一个字符。如果是新行,则用 NULL 替换它。否则我们知道输入比 fgets() 中提供的 int 更多。所以我们所要做的就是吃掉输入缓冲区中剩余的字符。

这是一个例子:

   char str1[5];
   char str2[5];
   fgets(str1,5,stdin);

   if(strlen(str1)>0){//to avoid Undefined Behavior in case of null byte input

       if(str1[strlen(str1)-1]=='\n'){

           str1[strlen(str1)-1]='\0';
       }
       else{

           while((getchar())!='\n');//eating the remaing chars in the buffer
       } 
   }

   fgets(str2,5,stdin);


   if(strlen(str2)>0){

      if(str2[strlen(str2)-1]=='\n'){

         str2[strlen(str2)-1]='\0';

      }
      else{

         while((getchar())!='\n');
      }

   }
   printf("\n1.%s\n2.%s",str1,str2);

您甚至可以使用 strol 或 sscanf 将使用 fgets 获得的字符串转换为浮点数和整数,但注意它们可能不会显示独立行为。

现在回到问题的解决方案:

#include <stdio.h>
#include <string.h>

int main(){
    char s1[100],s2[100],s3[100];
    char ch[2];//make ch atleast 2 char wide

    fgets(s1,100,stdin);
     if(strlen(s1)>0){

          if(s1[strlen(s1)-1]=='\n'){

             s1[strlen(s1)-1]='\0';

          }
          else{

             while((getchar())!='\n');
          }

    }

   fgets(s2,100,stdin);
     if(strlen(s2)>0){

          if(s2[strlen(s2)-1]=='\n'){

             s2[strlen(s2)-1]='\0';

          }
          else{

             while((getchar())!='\n');
          }

    }

   fgets(s3,100,stdin);
     if(strlen(s3)>0){

          if(s3[strlen(s3)-1]=='\n'){

             s3[strlen(s3)-1]='\0';

          }
          else{

             while((getchar())!='\n');
          }

    }    

    fgets(ch,2,stdin);
      if(strlen(ch)>0){

          if(ch[strlen(ch)-1]=='\n'){

              ch[strlen(ch)-1]='\0';

          }
          else{

              while((getchar())!='\n');
          }

     }

    if(isalpha(ch[0]) && (s1[0]==ch[0] || s2[0]==ch[0] || s3[0]==ch[0]))
        printf("yes");
    else
        printf("no");

        return 0;
}

【讨论】:

    【解决方案2】:

    试试 fgets。

    fgets(s1,100,stdin);
    fgets(s2,100,stdin);
    fgets(s3,100,stdin);
    

    【讨论】:

      【解决方案3】:
      #include <stdio.h>
      int main(){
      char s1[100],s2[100],s3[100];
      char ch[1];
      
      fgets(s1,100,stdin);// like gets but limited by length
      fgets(s2,100,stdin);
      fgets(s3,100,stdin);
      
      scanf("%s",ch);
      
      if( (s1[0]>='a' && s1[0]<='z') || (s1[0]>='A' && s1[0]<='Z') ){//ch-alpha?
          if(s1[0] == ch[0]){  printf("yes"); }//s1[0] == ch[0] ??
          else{ printf("no"); }
          }
      else
          printf("no"); return 0; }
      

      【讨论】:

      • 如果用户输入一个大于 100 个字符的字符串,它会将其分配给下一个 fgets,事情就会一团糟
      猜你喜欢
      • 2022-01-05
      • 2019-12-08
      • 1970-01-01
      • 2012-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多