【问题标题】:2-D array in string creating erroneous output in C字符串中的二维数组在 C 中创建错误输出
【发布时间】:2015-02-22 20:43:22
【问题描述】:

我正在尝试做一些简单的事情,比如打印字符串的反转。 示例:

Hello World! This is me

需要的O/P:

me is This World! Hello

我的代码是这样的:

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

int main(){
 char *arr[20] ;
 int i,j;
 int size;
 char *revarr[20];
 printf(" enter the number of words\n");
 scanf("%d",&size);
 for(i=0;i<size;i++)
 scanf("%s",&arr[i]);
 for(i=0;i<size;i++)
 {

    printf("%s\n",&arr[size-1-i]); //overwritten words
    revarr[i]=arr[size-1-i];
 }
 printf(" the reversed sentence is %s\n",(char *)revarr);
}

我除了 arr[0] , arr[1] 等是单独的实体,但在打印和存储它们时,它们似乎是这样重叠的: 我/p:

Hello World

o/p:

World
HellWorld
the reversed sentence is WorlHell@#$

我似乎无法弄清楚出了什么问题! 提前致谢!

编辑: 打印时

printf(&arr[0]);
printf(&arr[1]);

我明白了:

HellWorld
World

我期望它打印的是

Hello
World

【问题讨论】:

  • 看起来 OP 打算这样做,因为 j 已声明但从未使用过...
  • 即使我尝试 print(&arr[0]) 和 print(&arr[1]) 我得到不正确的单词!
  • 无论如何,这不是一个嵌套循环。

标签: c string multidimensional-array


【解决方案1】:

您将arrrevarr 声明为char 指针数组。您需要为其元素动态分配内存。
另请注意,您不需要在语句中使用&amp;

scanf("%s",&arr[i]);  

printf("%s\n", &arr[size-1-i]);  
//             ^No need of &  

这是您的代码的修改版本。请注意,不需要使用revarr 来反转字符串。

#include<stdio.h>
#include<stdlib.h>

int main(){
    size_t i, size;
    printf("Enter the number of words\n");
    scanf("%d", &size);
    char *arr[size] ;  // Variable length array. Supported by C99 and latter

    for(i = 0; i < size; i++) 
    {
        arr[i] = malloc(20); // Assumimg words are no longer than 20 characters
        scanf("%s", arr[i]);
    }

    printf("The reversed sentence is:\n");  
    for(i = size-1; i >= 0; i--)  // Run loop in reverse order and print words
        printf("%s ", arr[i]); 
}

【讨论】:

  • 或者,既然包含了string.h,就用字符串吧?
  • @dodexahedron;不!在 C 中没有 string 类型。
  • 是的,如果 C. 我在 C++ 领域并思考 std::string。
  • 在我看来,这是最优雅的解决方案:鉴于每个单词都是 OP 帖子的单独字符串条目,因此不需要 revarr[] 或字符串复制:只是一个反向循环。跨度>
  • 直截了当:1+;但是仍然挑剔,isize 应该是 size_ts。
【解决方案2】:

在使用arr[0], arr[1],等读取字符串之前,您还没有为它们分配内存

scanf("%s",&arr[i]);

这是未定义行为的原因。你需要这样的东西:

int main(){
   char *arr[20] ;
   int i,j;
   int size;
   char *revarr[20];
   printf(" enter the number of words\n");
   scanf("%d",&size);
   for(i=0;i<size;i++)
   {
      // Allocate memory.
      // make it large enough to hold the input
      arr[i] = malloc(100);
      scanf("%s", arr[i]);
   }
   for(i=0;i<size;i++)
   {
      revarr[i]=arr[size-1-i];
   }

   printf(" the reversed sentence is: ");
   for(i=0;i<size;i++)
   {
       printf("%s ", revarr[i]);
   }
   printf("\n");


   // Deallocate the memory.
   for(i=0;i<size;i++)
   {
      free(arr[i]);
   }

   return 0;
}

【讨论】:

  • printf(" the reversed sentence is %s\n",(char *)revarr); 不起作用
  • ...除了缺少的return 0; ;-)
  • 为什么我不能使用 typecast to (char *) 然后打印 revarr?是因为 '\0' scanf 会附加在每个单词之后,这不会让我打印整个语句吗?
  • 因为revarr[] 是一个指向每个单词(字符串)的指针数组。这就是为什么@RSahu 循环使用for(i=0;i&lt;size;i++) printf("%s ", revarr[i]); 打印每个
  • return 0; 可以省略。
【解决方案3】:

这是解决您问题的好方法:

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

int main(int argc, char *argv[])
{
     /* the string line will contain the line of the  input */
     char line[100];
     /* read the string with the function f gets */
     fgets(line,100,stdin);
   /* the tab will contain all the string of the variable  line */
     char *tab[20];
     /* the variable p will point to each string of the  line */
     char *p=NULL;
     /* we extract the strings of the line via the function strtok */
     p=strtok(line," ");
     int nb=-1;
     while (p!=NULL)
     {
         nb++;
         /* we allocate a space memory fo every str ing  */
            tab[nb]=malloc(sizeof(char)*100);
            strcpy(tab[nb],p);
            p=strtok(NULL," ");
     }
     /* there is an exception with the last string of the line we need to take care o f it */
     tab[nb][strlen(tab[nb])-1]='\0';
     int i;
     /* print the strings in reverse or der  */
     for (i=nb;i>=0;i--)
     {
         printf("%s ",tab[i]);
        /* dont forget to free the space memory at the end of the prog ram  */
         free(tab[i]);
     }
     printf("\n");

     return 0;
}

【讨论】:

    【解决方案4】:

    您需要以下内容

    #include <stdio.h>
    #include <string.h>
    
    int main(void) 
    {
        size_t size;
    
        printf( "enter the number of words: " );
        scanf( "%zu", &size );
    
        char arr[size][20];
        char revarr[size][20];
    
        for ( size_t i = 0; i < size; i++ ) scanf( "%s", arr[i] );
    
        printf( "\n" );
    
        for ( size_t i = 0; i < size; i++ ) strcpy( revarr[i], arr[size-i-1] );
    
        printf( "the reversed sentence is"  );
    
        for ( size_t i = 0; i < size; i++ ) printf( " %s", revarr[i] );
        printf( "\n" );
    
        return 0;
    }
    

    如果进入

    2
    Hello World
    

    然后输出将是

    World Hello
    

    请注意,仅当您的编译器支持 C99 时才会编译代码。否则你必须为字符数组动态分配内存。

    至于您的代码,它具有未定义的行为,并且总体上是无效的。您没有为数组arrrevarr 的每个元素分配内存。您不能将一个数组分配给另一个数组。相反,您必须使用标准函数strcpy 等等。

    【讨论】:

    • 是的,该解决方案对于 C 来说看起来不错。另外,对于 size_t,我猜我可能需要导入不同的头文件。谢谢!
    • 但我认为在 for 循环中定义变量仅适用于 C++!我说的对吗?
    • @joanOfArc 实际上这是最好的解决方案,因为它更接近您没有动态分配数组的代码。它基于可变长度数组。当然使用 fgets 会更好,但在这种情况下程序会更复杂。
    • @user12448 我在回答中写道,编译器应该支持 C99。否则需要做一些小的改动。
    • @joanOfArc 20 是每个单词的最大字节数。也就是说,您可以定义例如 char word[20];你在问用户你要输入多少字。所以大小是单词的数量。结果你会得到 char word[size][20]
    猜你喜欢
    • 2021-04-04
    • 1970-01-01
    • 2019-01-21
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2019-01-28
    • 1970-01-01
    相关资源
    最近更新 更多