【问题标题】:Strings in a FOR loopFOR 循环中的字符串
【发布时间】:2017-01-02 03:23:38
【问题描述】:

我有一个问题。

我想要一个 FOR 循环来打印许多字符串的文本。假设我输入了我的名字和姓氏。并且 FOR 循环产生字符串。

#include <stdio.h>
int main(){

   char str1 [12];
   char str2 [12];
   char wordarray [2]={str1,str2}; // error here
   int i;

   printf ("Type your forname : ");
   scanf ("%s",&str1);
   printf ("\nType your last name : ");
   scanf ("%s",&str2);

   printf ("\n\nYour name is : ");
   printf ("%s\t%s",str1,str2);
   printf ("\n");

   for (i=0;i<3;i++){
      printf ("%s",wordarray [i]); // Error here . 
   } // end FOR

   return 0;
} // end MAIN

【问题讨论】:

  • this:"prints back text many strings" 是什么意思?
  • 您收到了哪些错误消息?
  • 第 1 步:修复由 char wordarray [2]={str1,str2}; 引起的错误/警告。使用char *wordarray [2]={str1,str2};
  • 鉴于所示代码甚至无法编译,您声称程序退出循环的说法是虚假的。尝试提供演示您问题的实际代码示例。
  • 使用scanf 输入字符串时要非常小心。如果您的用户输入的 return 没有字符,或者名字或姓氏超过 11 个字符,您就有麻烦了。更好的选择是fgets,但您仍然需要测试超过您提供的 12 个字符的名称。

标签: c arrays string loops for-loop


【解决方案1】:

您需要使用scanf(或您用于用户输入的任何函数)验证每次读取,以确保您有有效的数据可供使用。您还应该为读取提供宽度限制,以确保您不会读取超出数组末尾的内容。 (例如scanf ("%11s", str1))。您应该考虑使用fgets 进行用户输入,并删除缓冲区中fgets 包含的'\n'。这将帮助您避免使用scanf 时经常困扰新用户的一些陷阱,尤其是在接受混合字符串和数字输入时。

除此之外,您还应该避免在代码中使用幻数(例如char str1[12])。如果您需要一个常量 12,则需要一个 define 或声明一个 enum 来创建它。

将这些部分放在一起,您可以执行以下操作:

#include <stdio.h>

#define LEN 12

int main (void) {

    char str1 [LEN] = "";
    char str2 [LEN] = "";
    char *wordarray[] = {str1, str2};
    int i, nwords = sizeof wordarray/sizeof *wordarray;

    printf ("Type your forname   : ");
    if (scanf ("%11s", str1) != 1) {
        fprintf (stderr, "error: invalid input.\n");
        return 1;
    }
    printf ("Type your last name : ");
    if (scanf ("%11s", str2) != 1) {
        fprintf (stderr, "error: invalid input.\n");
        return 1;
    }

    printf ("\nYour name is : %s %s\n", str1, str2);

    for (i = 0; i < nwords; i++){
        printf ("%s", wordarray [i]);
    }
    putchar ('\n');

    return 0;
}

使用/输出示例

$ ./bin/name
Type your forname   : david
Type your last name : rankin

Your name is : david rankin
davidrankin

检查一下,考虑其他答案,如果您还有其他问题,请告诉我。还要考虑我对零输入或超过 12 个字符的输入的评论。这将有助于在您的输入处理中建立稳健性。

如果您想使用fgets 处理输入,您可以通过以下方式稍微改进您的输入处理:

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

#define LEN 12

int main (void) {

    char str1 [LEN] = "",
         str2 [LEN] = "",
         *wordarray[] = {str1, str2};
    size_t i, len = 0, nwords = sizeof wordarray/sizeof *wordarray;

    printf ("Type your forname   : ");
    if (!fgets (str1, LEN, stdin)) {    /* read with fgets/validate */
        fprintf (stderr, "error: invalid input.\n");
        return 1;
    }
    len = strlen (str1);                /* get length of str1     */
    if (str1[len-1] == '\n')            /* test for trailing '\n' */
        str1[--len] = 0;                /* overwrite with nulbyte */

    printf ("Type your last name : ");
    if (!fgets (str2, LEN, stdin)) {
        fprintf (stderr, "error: invalid input.\n");
        return 1;
    }
    len = strlen (str2);
    if (str2[len-1] == '\n')
        str2[--len] = 0;

    printf ("\nYour name is : %s %s\n", str1, str2);

    for (i = 0; i < nwords; i++){
        printf ("%s", wordarray [i]);
    }
    putchar ('\n');

    return 0;
}

【讨论】:

    【解决方案2】:

    你不明白数组和指针是如何工作的。你应该阅读这个answer。

    #include <stdio.h>
    
    int main(void) {
      printf("Type your forname : ");
      char str1[12];
      { // we open a scope because ret don't need to be in function scope
        int ret = scanf("%11s", str1); // scanf need to know how many bytes are
        // available without count `\0` and you must send the array itself not the
        // address
        if (ret != 1) {                        // scanf don't set str1
          fprintf(stderr, "Error in input\n"); // stderr is the error stream
          return 1;
        }
      }
    
      printf("\nType your last name : ");
      char str2[12];
      {
        int ret = scanf("%11s", str2);
        if (ret != 1) {
          fprintf(stderr, "Error in input\n");
          return 1;
        }
      }
    
      printf("\n\nYour name is : ");
      printf("%s\t%s", str1, str2);
      printf("\n");
    
      char *word[2] = {str1, str2}; // we need an array of pointer
      for (size_t i = 0; i < sizeof word / sizeof *word; i++) { // size of array
        printf("%s", word[i]);
      }
    
      return 0;
    }
    

    【讨论】:

      【解决方案3】:

      我不知道一切是如何运作的。这就是我问的原因:) 感谢您的回复。我会调查的。有了这些信息,我将尝试构建一个更大的 FOR-loop ,这样我就可以在二维数组中插入值。用户可以将值添加到二维数组,然后更改插槽中的信息文本或数字。

      #include <stdio.h>
      #define lenght 12                // corrected, define string format lenght
      
      int main(){
      
      char str1 [lenght];              // corrected, strings should have format lenght
      char str2 [lenght];              // corrected, strings should have format lenght
      char *wordarray [2]={str1,str2}; // corrected, add a * to wordarray[2]
      int i;
      
      printf ("Type your forname : ");
      scanf ("%s",str1);               // corrected, skip the & in ("%s",&str1);
      printf ("Type your last name : ");
      scanf ("%s",str2);               // corrected, skip the & in ("%s",&str2);
      
      printf ("\n\nYour name is : %s\t%s\n",str1,str2);
      
      for (i=0;i<2;i++){               // corrected, i<2 must match the array elements
      printf ("%s\t",wordarray [i]); 
      } // end FOR
      
      return 0;
      } // end MAIN
      

      【讨论】:

      • 哇,它可以在 ("%s",&str2) 中没有 & 的情况下工作。当我忘记它并在 scanf 上签名时,我通常会收到一个错误。
      • 阅读这个answer,这项工作是因为它是一个数组,但你不应该这样做。 &amp;str 具有类型 char (*)[12],scanf 期望 char *,阅读此 question。
      【解决方案4】:

      好的。又去了一次。 Havent 经常使用字符串。该程序在数组中有字符串和数字,并在 FOR 循环中打印。我还尝试让用户可以使用数组中的单个元素,以便他可以更改值。

      我想我的风格很糟糕。但是......这是我得到的。 现在关于GETS(str1),从用户那里获取一个字符串。在程序中第一次使用时,它表现正常。但是在程序中第二次我不得不使用GETS(“%s”,str1)所以它表现得很好。还有一个问题是从用户确定的数组中添加特定数字。显示在 for 循环中...

      另一个问题是在 JUMP 之后清除控制台屏幕。所以文字不会淹没屏幕。

      评论:我同意 David C. Rankin 的观点,即验证用户数据很重要。仅允许字符串请求中的字符输入和整数请求中的数字。如果像斜线或点这样的“特殊字符”,也会返回错误输入。我试着阅读原始的 K&R C 书,他们谈到了它,主题比如将所有字母变成小写字母或大写字母。但我在运行示例代码时遇到了麻烦,可能是 C89 C11 编译器问题,我不知道。

      #include <stdio.h>
      //#include <string.h> // GCC32-C . mingw . compile
      #define lenght 20    // Orbit_L75.Apartment_9
      
      int main(){
      
      int i,j,k,select,select2,*ptr;
      char str1 [lenght];              
      char str2 [lenght];             
      char *wordarray [2]={str1,str2}; // character array must have a * asterix  pointer . 
      int numarray [2];
      
      printf ("Type your forname : ");
      gets (str1); // gets (wordarray[0]) // alternative syntax       
      printf ("Type your last name : ");
      gets (str2);            
      
      printf ("Enter your telephone number : ");            
      scanf ("%d",&numarray[0]);     // assign a value to numarray slot 0
      //scanf ("%d",(numarray+0));  // alternative syntax
      
      printf ("Enter your age : ");
      scanf ("%d",&numarray[1]); // assign a value to numarray slot 1
      printf ("\n\n");
      
      jump1 : 
      printf ("=========================\n");
      for (i=1;i<5;i++)
      {printf ("%d\t",i);}
      printf ("\n");
      
      for (j=0;j<2;j++)
      {printf ("%s\t",wordarray[j]);}
      //printf ("%s\t",*(wordarray+j));} //  alternative syntax
      printf ("\n");
      
      for (k=0;k<2;k++)
      {printf ("%d\t",numarray[k]);}
      printf ("Sum = %d\n",(numarray[0]+numarray[1]));     // add numarray slot 0 and slot 1.
      //printf ("Sum = %d",*(numarray+0)+*(numarray+1));  // alternative syntax
      printf ("=========================\n");
      
      printf ("\n\nSelect\n1: Change Telephone \n2: Change Age \n3: Change First Name \n4: Change Last Name \n5: RAM location\n");
      scanf ("%d",&select);
      
      if (select == 1)
      {printf ("New number : ");
      scanf ("%d",&numarray[0]);
      //scanf ("%d",(numarray+0));               // alternative syntax
      printf ("\n");}
      
      else if (select == 2)
      {printf ("New age : ");
      scanf ("%d",&numarray[1]);
      printf ("\n");}
      
      else if (select == 3)
      {printf ("New First Name : ");
      scanf ("%s",str1); //problems with the display using GETS on the second run.
      printf ("\n");} 
      
      else if (select == 4)
      {printf ("New Last Name : ");
      scanf ("%s",str2);
      printf ("\n");}
      
      else if (select == 5)
      { // select2
      {printf ("\nRAM location of : \n\t1. Telephone number\n\t2. Age\n\t3. First Name.\n\t4. Last Name\n");}
      scanf ("%d",&select2);
      
      if (select2 == 1)
      {ptr = &numarray[0];
      printf ("\nTelephone number\nValue in Decimal\t: %d\nValue in Hexadecimal\t: %ph\nRAM location in decimal\t: %d\nRAM location in Hex\t: %ph\n\n\n",*ptr,*ptr,ptr,ptr);}
      
      else if (select2 == 2)
      {ptr = &numarray[1];
      printf ("\nAge\nValue in Decimal\t: %d\nValue in Hexadecimal\t: %ph\nRAM location in decimal\t: %d\nRAM location in Hex\t: %ph\n\n\n",*ptr,*ptr,ptr,ptr);}
      
      else if (select2 == 3)
      {ptr = &wordarray[0];
      printf ("\nFirst Name\nValue in Text\t: %s\nValue in Hexadecimal\t: %ph\nRAM location in decimal\t: %d\nRAM location in Hex\t: %ph\n\n\n",*ptr,*ptr,ptr,ptr);}
      
      else if (select2 == 4)
      {ptr = &wordarray[1];
      printf ("\nLast Name\nValue in Text\t: %s\nValue in Hexadecimal\t: %ph\nRAM location in decimal\t: %d\nRAM location in Hex\t: %ph\n\n\n",*ptr,*ptr,ptr,ptr);}
      
      else if (select2 <1 || select2 > 4)
      {printf ("\nValue is out of range, Try again .\n\n");}
      } // end IF select2
      
      else if (select <1 || select > 5)
      {printf ("\nValue is out of range, Try again .\n\n");}
      
      goto jump1;
      
      return 0;
      } // end MAIN
      

      【讨论】:

        【解决方案5】:

        str1 和 str2 实际上是指针。

        wordarray 是一个字符数组。它应该是一个指向 char 的指针数组。

        同样在你的 scanf 中你传递了 str1 和 str2 的地址,但你应该只传递 str1 和 str2。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-03-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-22
          • 2011-09-18
          • 2019-08-31
          • 1970-01-01
          相关资源
          最近更新 更多