说明
我用fgets()读取userinput(例如" ls -l /")并调用Parse(),它被分开(" ls"" -l&# 34;" \")供以后使用。
问题是:来自第一个周期的令牌中有令人毛骨悚然的字符(下面的屏幕截图),但从那里输出就很好了。 我试图用零来初始化两个缓冲区而不改变行为。请解释我的第一个输出中发生的事情。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/times.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
typedef char* string;
char inputBuffer[512];
string parse[256];
int j,parseCount;
void Parse(void);
void Parse(void)
{
char buffer[512];
string token;
token = " ";
strcpy(buffer, inputBuffer);
j=0;
parse[j] = strtok (buffer, token);
while (parse[j] != NULL)
{
j++;
parse[j] = strtok (NULL, token);
}
parseCount =j;
}
int main (void)
{
printf(">> ");
fgets(inputBuffer, 512, stdin); /* input buffer, max.Input(char), whereFrom?*/
Parse();
for (j=0;j<parseCount;j++){
printf("[%d] %s\n",j, parse[j]);
}
return main();
}
答案 0 :(得分:4)
这一行
parse[j] = strtok (buffer, token);
将内存地址存储在buffer
中,Parse()
是本地的。{1}}。返回buffer
时,代表Parse()
的内存无效,因此当尝试取消引用以打印它们所引用的内容时,parse
中存储的地址也将无效。
要解决此问题,请调用函数创建一个临时工作缓冲区并向下传递给`Parse()对它的引用:
char * parse[256] = 0;
char buffer[512] = "";
size_t parseCount = 0;
void Parse(char * buffer)
{
const char * token = " ";
size_t j = 0;
parse[j] = strtok(buffer, token);
while (parse[j] != NULL)
{
j++;
parse[j] = strtok(NULL, token);
}
parseCount = j;
}
int main(void)
{
fgets(buffer, 512, stdin);
{
char buffer_tmp[512];
strcpy(buffer_tmp, buffer);
Parse(buffer_tmp);
for (size_t j = 0; j < parseCount; j++)
{
printf("[%zu] %s\n", j, parse[j]);
}
}
return 0;
}
由于我不喜欢全局变量,我更喜欢以下内容:
#include <stdio.h>
#include <string.h>
size_t parse(char * buffer, char ** parse)
{
const char * token = " ";
size_t j = 0;
parse[j] = strtok(buffer, token);
while (parse[j] != NULL)
{
j++;
parse[j] = strtok(NULL, token);
}
return j;
}
#define IN_MAX (512 + 1 + 1)
int main(void)
{
char buffer[IN_MAX] = "";
if (NULL != fgets(buffer, IN_MAX, stdin))
{
char buffer_tmp[IN_MAX];
strcpy(buffer_tmp, buffer);
{
size_t parse_count = 0;
char * parse[IN_MAX/2 + 1] = 0;
size_t parse_count = parse(buffer_tmp, parse);
for (size_t j = 0; j < parse_count; j++)
{
printf("[%zu] %s\n", j, parse[j]);
}
}
}
else if (ferror())
{
fprintf(stderr, "Error reading from inout stream.\n");
}
return 0;
}