小c程序中的奇怪括号

小c程序中的奇怪括号,c,C,我正在用C编写一个简单的程序: int main(int argc, char** argv) { unsigned char* line = (unsigned char* ) malloc(0xFFFF); while (gets(line) > 0) { if (line[0] == 'l') { if (line[2]=='.' && line[3] == '.') { prin

我正在用C编写一个简单的程序:

int main(int argc, char** argv) {
    unsigned char* line = (unsigned char* ) malloc(0xFFFF);
    while (gets(line) > 0) {
        if (line[0] == 'l') {
            if (line[2]=='.' && line[3] == '.') {
                printf("forbidden path");
            } 
            unsigned char* res = (unsigned char* ) malloc(0xFFFF);
            unsigned char* cmd = (unsigned char* ) malloc(strlen(line) +
            1 + strlen(" | grep -v xml") + strlen("/home/files/"));
            strcpy(cmd, "ls ");
            strcpy(cmd + 3, "/home/boris/0servfiles/");
            strcpy(cmd + 3 + strlen("/home/files/"), line + 2);
            strcpy(cmd + 3 + strlen("/home/files/") + strlen(line + 2), " | grep -v xml");
            execwthr(cmd, res);
            printf("%s\n%s", cmd, res);
            free(cmd);
            free(res);
        } else if (line[0] == 'm') {
            if (line[2]=='.' && line[3] == '.') {
                printf("forbidden path");
            } 
            unsigned char res = (unsigned char* ) malloc(0xFFFF);
            unsigned char* cmd = (unsigned char* ) malloc(strlen(line) +
                1 + strlen("/home/files/"));
            strcpy(cmd, "mkdir ");
            strcpy(cmd + 6, "/home/files/");
            strcpy(cmd + 6 + strlen("/home/files/"), line + 2);
            execwthr(cmd, res);
            printf("%s\n%s", cmd, res);
            free(cmd);
            free(res);
        }
    }
    return (EXIT_SUCCESS);
}
有一个小问题。当我尝试创建名为“h”的文件夹时,我得到以下信息:

m l
mkdir /home/files)l

怎么了?提前谢谢

您似乎不知道
strcat()
函数。使用它将大大简化您的代码

另外,为什么要编写C代码来完成一项可以用简单的shell(或Perl)脚本轻松完成的工作?例如,我相信您的脚本在Perl中会像这样:

#!/usr/bin/perl
use strict;
while (my $line = <STDIN>) {
    chomp $line;
    my $cmd;
    if (my ($arg) = $line =~ m{^l (.*)$}) {
        $cmd = "ls /home/files/$arg | grep -v xml";
    } elsif (my ($arg) = $line =~ m{^m (.*)$}) {
        $cmd = "mkdir /home/files/$arg";
    }
    my $res = `$cmd`;
    print "$cmd\n$res\n";
}
#/usr/bin/perl
严格使用;
while(我的$line=){
chomp$行;
我的$cmd;
如果(my($arg)=$line=~m{^l(.*$}){
$cmd=“ls/home/files/$arg | grep-v xml”;
}elsif(my($arg)=$line=~m{^m(.*$}){
$cmd=“mkdir/home/files/$arg”;
}
我的$res=`$cmd`;
打印“$cmd\n$res\n”;
}

请注意,此代码未经测试,并且(仍然)不安全。但是,它比您的代码短得多,也更容易阅读。这表明C语言不适合此任务。:)

这段代码相当糟糕。请参考功能

我还看到许多其他问题。例如,如果代码确定输入了“禁止路径”,那么它将继续执行任务


您将受益于学习如何使用调试器逐步完成此代码,并了解它的实际功能。这也让你能够回答你原来的问题。

这里有很多问题。我将列出一些,解决它们可能会使其他问题更加明显

当意外路径显示为输入时,打印出“禁止路径”。但是,您可以使用该无效路径继续执行该函数。发生这种情况时,您可能希望完全退出程序

malloc()
函数可能会失败。当它这样做时,它返回一个空指针。您从不检查malloc返回的值,这意味着您的字符串操作代码可能使用了无效指针

您不应该使用像strcpy()这样的函数,因为它们不能防止缓冲区溢出。改用“安全”版本(如
strncpy

函数
gets()
非常不安全,已被弃用。请改用其他标准库I/O函数

此代码:

strcpy(cmd, "ls ");
strcpy(cmd + 3, "/home/boris/0servfiles/");
strcpy(cmd + 3 + strlen("/home/files/"), line + 2);
可能没有做你想让它做的事。第二行向缓冲区添加一个长字符串,但第三行只向前跳过足够远的距离,以容纳一个更短的字符串。这意味着您的第三个
strcpy
将部分覆盖第二个
strcpy
编写的字符串

代码如下:

strcpy(cmd, "mkdir ");
strcpy(cmd + 6, "/home/files/");
strcpy(cmd + 6 + strlen("/home/files/"), line + 2);
容易出错,而且充满了神奇的数字。如果我正确地解释了您正在做的事情,那么您可以将其组合成一个更有意义的调用:
sprintf(cmd,“mkdir/home/files/%s”,第+2行)

正如其他人所提到的,您似乎正在重新实现标准的
strncat()
函数。您最好使用标准版本。如果您正在处理这样的硬编码字符串,我甚至建议您使用
snprintf()

下面的行是错误的:

unsigned char res = (unsigned char* ) malloc(0xFFFF);
您正在将指针分配给
字符
,这几乎肯定不是您想要的


您可以动态地为
分配内存,但从来没有释放过它。

基本上,所有难看的代码都可以通过使用正确的参数调用
snprintf
来替换。不要费心学习strcat;正如其他人所说,这将比您正在做的更容易,同时也使编写易受攻击的代码变得更容易。只要使用
snprintf
满足您所有的字符串生成需求,您的代码就会变得干净、简单,甚至有很好的机会没有bug。

亲爱的上帝,这是什么代码?这段代码太难看了,它伤害了我的眼睛调试提示:分别解决字符串操作和与文件系统部分的交互问题。事实上,这两个函数可以很好地解决这个问题。说真的,现在停下来,读一本关于C的好书。只要用C in替换“数据库”。在某个时候,您应该解释一下
execwthr()
函数的作用。这样拼写,谷歌指向的唯一相关链接是这个问题。您还应该忘记函数调用
gets()
是存在的。
malloc
失败是他最不担心的。和。