在C中填充字符串数组的正确方法是什么,这样每个字符串都是数组中的单个元素

时间:2016-10-12 18:22:14

标签: c multidimensional-array

我试图在C中初始化一个二维字符串数组;这似乎与我编写的任何其他语言不同。我正在尝试做的是读输入,并从该输入中取出所有注释并将它们存储在二维数组中,其中每个字符串都是数组中的新行。当我到达下一行的字符时,我想推进数组的第一个索引,以便我可以将每个"注释字符串"分开。即。

   char arr[100][100];

   <whatever condition>
   arr[i][j] = "//First comment";

然后当我到达&#39; / n&#39;我想增加第一个索引,以便:

   arr[i+1][j] = "//Second comment";

我只是希望能够将每个输入作为我的数组中的单个元素进行访问。在Java中,我不需要这样做,因为每个字符串已经是String数组中的单个元素。我现在只和c一起工作了3个星期,而我过去认为理所当然的事情很简单,事实证明在C中非常令人沮丧。

我的实际代码如下。它给了我一个无限循环并打印出大量的数字:

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

const int MAXLENGTH = 500;

int main(){
    char comment[MAXLENGTH][MAXLENGTH];
    char activeChar;
    int cIndex = 0;
    int startComment = 0;
    int next = 0;

    while((activeChar = getchar()) != EOF){
        if(activeChar == '/'){
            startComment = 1;
        }

        if(activeChar == '\n'){
            comment[next][cIndex] = '\0';
            next++;
        }

        if(startComment){
            comment[next][cIndex] = activeChar;
            cIndex++;
        }
    }

    for(int x = 0 ; x <  MAXLENGTH; x++){
        for (int j = 0; j < MAXLENGTH; j++){
            if(comment[x][j] != 0)
            printf("%s", comment[x][j]); 
        }
    }

    return 0;
}

2 个答案:

答案 0 :(得分:1)

comment是一个字符的2D数组,它是单个字符。在C中,字符串只是一个字符数组,因此您对注释的定义是定义一维字符串数组的一种方法。

就负载而言,唯一明显的潜在问题是你没有将startComment重置为零(但你应该使用调试器来确保它正确加载),不过你的打印出来的代码是错误的。

使用带有%s的printf()告诉它开始在你给它的任何地址打印字符串,但是你要给它单独的字符,而不是整个字符串,所以它解释每个字符每个字符串(因为C是一种可怕的,可怕的语言)作为RAM中的地址并尝试打印该RAM。要打印单个字符,请使用%c而不是%s。或者,只需为循环创建1D:

for(int x=0; x<MAX_LENGTH; X++)
    printf("%s\n", comment[x])   

对于数组中的行数和每行中字符串的长度,使用相同的MAX_LENGTH也有点令人困惑

答案 1 :(得分:1)

你遇到的问题是C本质上是一个美化的汇编程序。这意味着它“内置”的唯一东西是有明显正确方法的东西。字符串符合此条件。因为这样的字符串不是c中的一阶公民。

特别是至少有三种可行的方法来处理字符串,C不会强迫你使用任何字符串,而是允许你使用你想要的工作。

方法1:静态数组

此方法似乎与您尝试执行的操作类似,并且通常由新的C程序员使用。在这个方法中,字符串只是一个字符数组,其长度足以适合其内容。分配数组变得困难,因此这促使使用字符串作为不可变的。这似乎是大多数JVM实现字符串的方式。 C代码:char my_string[] = "Hello";

方法2:静态有界数组

这种方法就是你正在做的。您确定您的字符串必须短于指定的长度,并为它们预先分配足够大的缓冲区。在这种情况下,分配字符串并更改它们相对容易,但它们不得长于设定的长度。 C代码:char my_string[MAX_STRING_LENGTH] = "Hello";

方法3:动态数组

这是最先进和最危险的方法。在这里,您可以动态分配字符串,以便它们始终适合其内容。如果它们变得太大,你就会调整大小。它们可以通过多种方式实现(通常作为单个char指针,根据需要与方法2一起重新分配,偶尔作为链表)。

无论你如何实现字符串,对于C来说,它们都只是字符数组。唯一需要注意的是,要使用标准库,您需要手动终止字符串(尽管许多[all?]指定了通过手动指定长度来解决此问题的方法)。

这就是为什么java字符串不是原始类型,而是String类型的对象。

有趣的是,许多语言实际上对这些解决方案使用不同的String类型。例如,Ada对上述三种方法都有StringBounded_StringUnbounded_String

解决方案

再次查看您的代码:char arr[100][100];这是哪种方法,它是什么?

显然,方法2的MAX_STRING_LENGTH为100.所以你可以假装线说:my_strings arr[100]这使你的问题显而易见,这不是一个2D数组的字符串,而是一个2D数组表示一维字符串数组的字符。要在C中创建一个2D字符串数组,您可以使用:char arr[WIDTH][HEIGHT][MAX_STRING_LENGTH]这很容易出错。但是,如上所述,您的代码中存在一些逻辑错误,并且您可以使用一维字符串数组来解决此问题。 (二维字符阵列)