我是C的初学者,我正在尝试创建一个像这样保存的字符串数组:
[1] [firststring]
[2] [secondstring]
[2] [thirdstring]
我的实现如下:
int counter = 0;
char for_pole[50][50];
strcpy(for_pole[counter][50],"hello");
counter++;
//then i want to print it:
printf("my string: %s", for_pole[0][50]); //prints out first string
printf("my string: %s", for_pole[1][50]); //...and second one
但返回分段错误。
我应该使用一些动态的内存分配吗? 正如我告诉我的新手,对不好的问题感到抱歉。
答案 0 :(得分:1)
我看不到代码中的第二个字符串。我只看到一个字符串“你好”。
您可以通过以下方式编写
int counter = 0;
char for_pole[50][50];
strcpy(for_pole[counter],"hello");
counter++;
strcpy(for_pole[counter],"world");
//then i want to print it:
printf("my string: %s\n", for_pole[0]); //prints out first string
printf("my string: %s\n", for_pole[1]); //...and second one
至于这个表达
for_pole[counter][50]
然后1)索引50在数组之外,因为索引的有效范围是0 - 49
和2)它具有类型char
而不是数组或指向char的指针函数strcpy
或格式说明符%s
。功能printf
。
答案 1 :(得分:1)
写作时
strcpy(for_pole[counter][50],"hello");
你正在写字符串"你好"到一个char。而且,它位于数组的位置50,从0到49。
你应该把它改成
strcpy(for_pole[counter],"hello");
因为" for_pole [i]"是第i个字符串和" for_pole [i] [j]"是该字符串的第j个字符。
同样,printf应为
printf("my string: %s", for_pole[0]);
我会添加一个' \ n'让事情变得更有条理
最后,代码将是这样的
int counter = 0;
char for_pole[50][50];
strcpy(for_pole[counter],"hello");
counter++;
printf("my string: %s\n", for_pole[0]); //prints out first string
printf("my string: %s\n", for_pole[1]); //prints out second string
答案 2 :(得分:0)
初始化for_pole变量为零。
char for_pole[50][50] = {0,};
答案 3 :(得分:0)
Jon.e,SEGFAULT有一些原因。 即使没有任何错误,也有缺乏记忆。
有些人告诉你,要注意编译器的消息和警告,是的,但这只是故事的一部分。
与SEGFAULT相关的是以下最值得注意的SEGFAULTS,我可以根据自己的经验告诉你:
<强> 1。您正在尝试访问不存在的索引。
数组的大小与声明数组时指定的大小完全相同。 查看此代码:
/* "Array out of bounds" error
valid indices for array foo
are 0, 1, ... 999 */
int foo[1000];
for (int i = 0; i <= 1000 ; i++)
foo[i] = i;
这里我们对一个不存在的索引进行非法访问。
<强> 2。您正尝试访问不存在的值。
在这种情况下,存在但存在值......
/* Illegal memory access if value of n is
not in the range 0, 1, ... 999 */
int n;
int foo[1000];
for (int i = 0; i < n ; i++)
foo[i] = i;
这也是最常见的陷阱之一。 这个陷阱是如此根本,即使是经验丰富的开发人员有时会犯这样的错误。问题在于变量n的未初始化的内存。 初始化是将变量的值作为第一个值的过程。如果你想,我们可以说它是失去变量的童贞的过程。 当变量初始化时以及何时 - 不是时,存在非常混乱的规则。复杂的记忆。只需要始终初始化变量。
第3。您正尝试通过指针访问内存。
那个指针并没有指向任何地方。你正试图从NOWHERE读一些东西?它没有意义,是吗?
/* Illegal memory access because no memory
is allocated for foo2 */
float *foo, *foo2;
foo = (float*)malloc(1000);
foo2[0] = 1.0;
如果您忘记初始化变量(2-nd)或指针(3-rd情况),会发生什么。答案很广泛:从无到有,都是灾难。
为什么这样?因为内存已被很多应用程序使用,并且它在计算机上运行的数十万个应用程序之间共享。因此,当您创建变量时,它会在内存中为这些变量创建段,但不会清除该内存(确切地说,在某些情况下,它已被清空,在其他情况下 - 不是)只是假设从未清除。所以在这种情况下,无论是由变量还是由指针引起的问题(实际上它也是一个变量,但那是另一个故事),我们说变量存储'垃圾'。
注意,找到那种SEGFAULTS并不是很明显,有时它几乎是不可能的,所以你必须为这种情况做好准备,并且应该使用调试器例如gdb来消除这个bug。
还要避免这样的虚假错误。与我的学生一起练习表明这是非常常见的错误。
int n = 100;
int foo[n];
改为使用
int foo[100]
或
const int n = 100;
int foo[n];
或
enum N { N = 100 };
int is[N];
其他参考: Can a const variable be used to declare the size of an array in C? https://kb.iu.edu/d/aqsj
答案 4 :(得分:0)
...字符串和数组索引如何协同工作。字符串是一个字符数组。例如,这是一个字符串:
char some_string[20] = "Hello";
这就是你打印它的方式:
printf("%s\n", some_string);
这就是你使用strcpy()
的方式:
strcpy(some_string, "Goodbye");
这就是你访问字符串中i
个字符的方式:
/* Not compilable by itself; just an example. */
some_string[i]
注意您使用[...]
的唯一时间是如何声明它并访问字符数组中的特定字符。但是,这是一个字符串。
对于字符串数组,您将其声明为二维字符数组,就像您使用for_pole
一样:
/* An array of 50 strings, all of which can store a maximum of 49
* characters, plus a null termination character for each string.
*/
char for_pole[50][50];
将strcpy()
与counter
字符串一起使用:
strcpy(for_pole[counter], "hello");
并打印第一个(0
- )字符串:
printf("my string: %s", for_pole[0]);
并打印第一个字符串的i
个字符:
printf("string[%d]: %c", i, for_pole[0][i]);
再次注意我每次都没有使用[50]
。如果您有一个字符串,则使用其名称和每个字符使用string[i]
访问它。如果您有一个字符串数组,则使用其名称和每个字符串使用array[i]
表示法访问该数组。要访问数组中j
个字符串的i
个字符:
/* Not compilable by itself; just an example. */
array[i][j]
您不需要像每个表达式那样使用[50]
。注意最后一个表达式array[i][j]
来访问单个字符。由于字符由整数值表示,因此编译器将在必要时将该整数转换为指针。
这意味着执行strcpy(for_pole[counter][50],"hello");
之类的操作会尝试复制字符串&#34; hello&#34;到编译器认为字符for_pole[counter][50]
成立的任何内存地址。例如,如果字符是字母A
,由我的系统上的整数65表示,那么程序将尝试复制字符串的所有6个字节&#34; hello&#34;到内存地址65.我的程序没有权限写入该内存地址,因此它是段错误的。这就是您遇到的问题。