麻烦\ 0 null终止字符串(C)

时间:2014-10-08 22:21:57

标签: c string null exec strtok

我似乎在使用\ 0终止字符串时遇到了一些麻烦。我不确定这是不是问题,所以我决定发帖。

首先,我将我的字符串声明为:

char *input2[5];

在程序的后面,我添加了这行代码,将所有剩余的未使用的插槽转换为\0,将它们全部更改为null终止符。可以用for循环完成,但是。是的。

while (c != 4) {
    input2[c] = '\0';
    c++;
}

在Eclipse中,当处于调试模式时,我看到空槽现在包含0x0,而不是\ 0。这些都是一样的吗?我声明为

的另一个字符串
char input[15] = "";

在调试模式下显示\ 000。

我的问题是我遇到了分段错误(在 Debian VM 上。但是在我的Linux 12.04上运行)。我的GUESS是因为字符串还没有真正终止,编译器不知道它什么时候停止,因此当数据显然已经超出限制时,它继续尝试访问数组中的内存。

编辑:我会尽快回答所有其他问题,但是当我将字符串声明更改为其他建议的问题时,我的程序崩溃了。有一个strtok()函数,用于将我的fgets输入切换为字符串,然后将它们放入我的input2数组中。

所以,

input1[0] = 'l'
input1[1] = 's'
input1[2] = '\n'

input2[0] = "ls". 

这是一个使用fork和execvp的shell模拟程序。我将很快发布更多代码。

关于建议:

  

char * input2 [5];这是完全合法的声明,但它   将input2定义为指针数组。要包含字符串,它需要   成为一个char数组。

我会再次尝试改变。我之前尝试过,但是我记得它给了我另一个运行时错误(seg fault?)。我认为这是因为我实现了我的strtok()函数的方式。我会再次检查出来。谢谢!

编辑2:我在下面添加了一个回复来更新我的进度。谢谢你的帮助!

It is here.

4 个答案:

答案 0 :(得分:3)

你的代码应该是这样的:

char input2[5];

for (int c=0; c < 4; c++) {
    input2[c] = '\0';
}

0x0和\ 0是相同值0的不同表示;

答案 1 :(得分:3)

回复1:

感谢所有答案!

我从响应中做了一些更改,但我还原了char建议(或正确的字符串声明),因为像有人指出的那样,我有一个strtok函数。 Strtok要求我发送一个char *,所以我又恢复了原来的状态(char * input [5])。我将我的代码发布到下面的strtok。我的问题是该程序在我的Ubuntu 12.04中工作正常,但是当我尝试在Debian VM上运行它时,会给我一个段错误。

我很困惑,因为我最初认为错误是因为编译器试图访问已经超出绑定的数组索引。这似乎不是问题,因为很多人都提到0x0只是另一种写作方式。我在下面发布了调试窗口的变量部分。尽管我能看到一切似乎都是正确的......嗯..

enter image description here

输入2 [0]和输入[0],输入[1]是焦点。

这是我的代码,直到strtok函数。其余的只是fork然后execvp调用:

int flag = 0;
int i = 0;
int status;
char *s; //for strchr, strtok
char input[15] = "";
char *input2[5];
//char input2[5];

//Prompt
printf("Please enter prompt:\n");

//Reads in input
fgets(input, 100, stdin);

//Remove \n
int len = strlen(input);
if (len > 0 && input[len-1] == '\n')
    input[len-1] = ' ';

//At end of string (numb of args), add \0

//Check for & via strchr
s = strchr (input, '&');
if (s != NULL) { //If there is a &
    printf("'&' detected. Program not waiting.\n");
    //printf ("'&' Found at %s\n", s);
    flag = 1;
}


//Now for strtok
input2[i] = strtok(input, " "); //strtok: returns a pointer to the last token found in string, so must declare
                                //input2 as char * I believe

while(input2[i] != NULL)
{
    input2[++i] = strtok( NULL, " ");
}

if (flag == 1) {
    i = i - 1; //Removes & from total number of arguments
}

//Sets null terminator for unused slots. (Is this step necessary? Does the C compiler know when to stop?)
int c = i;
while (c < 5) {
    input2[c] = '\0';
    c++;
}

答案 2 :(得分:1)

问:为什么你没有声明你的字符串char input[5];?你真的需要额外的间接水平吗?

问:while (c < 4) is safer。并确保初始化&#34; c&#34;!

是的,&#34; 0x0&#34;在调试器和&#39; \ 0&#39;在您的源代码中&#34;同样的事情&#34;。

建议更改:

char input2[5];
...
c = 0;
while (c < 4) {
    input2[c] = '\0';
    c++;
}

这几乎可以肯定会修复您的细分违规行为。

答案 3 :(得分:0)

char *input2[5];

这是一个完全合法的声明,但它将input2定义为一个指针数组。要包含字符串,它必须是char的数组。

while (c != 4) {
    input2[c] = '\0';
    c++;
}

同样,这是合法的,但由于input2是一个指针数组,input2[c]是一个指针(类型char*)。 空指针常量的规则是'\0'是有效的空指针常量。作业相当于:

input2[c] = NULL;

我不知道你要对input2做些什么。如果将它传递给期望char*指向字符串的函数,则代码将无法编译 - 或者至少会收到警告。

但是如果你想让input2持有一个字符串,则需要将其定义为:

char input2[5];

很遗憾,您所犯的错误恰好是C编译器未必诊断的错误。 (C中有太多不同的“零”口味,它们通常可以悄然互换。)