2015-10-19 19 views
-2

我试图用函数填充几个字符串,但字符串似乎没有被正确填充。 print语句只有4个空行。但如果我取消注释char ** pls行,它将正确打印所有三个字符串,即使我从不在任何地方使用变量pls。它也可以在调试模式下正常运行而不存在变量。我不完全确定我做了些什么,但并不高兴。函数调用中未填充C字符串

char * dataFile = (char *) calloc(64, sizeof(char)); 
//char ** pls = &dataFile; 
char * queryFile = (char *) calloc(64, sizeof(char)); 
char * outFile = (char *) calloc(64, sizeof(char)); 
for(i = 1; i <argc; ++i) 
{ 
    char command[3]; 
    char * iterator = argv[i]; 
    command[0] = *iterator; 
    ++iterator; 
    command[1] = *iterator; 
    ++iterator; 
    command[2] = *iterator; 

    if(strcmp(command, "df=") == 0) 
     determineFileString(iterator, &dataFile); 
    else if(strcmp(command, "if=") == 0) 
     determineFileString(iterator, &queryFile); 
    else if(strcmp(command, "of=") == 0) 
     determineFileString(iterator, &outFile); 
} 
printf("%s\n%s\n%s\n", dataFile, queryFile, outFile); 

void determineFileString(char * iterator, char ** file) 
{ 
    char * p = *file; 
    ++iterator; 
    while(*iterator != '\0') 
    { 
     *p = *iterator; 
     ++p; 
     ++iterator; 
    } 
    *p = '\0'; 
} 
+0

“即使我从不在任何地方使用变量,它会正确打印所有三个字符串”的味道像未定义的行为。 – Downvoter

+0

在C中不需要使用calloc,它的返回类型是void *。任何方式回来的代码,实际上编译来看看程序是如何工作的。 – Michi

回答

3

您打电话给strcmp但第一个操作数不指向一个字符串。一个字符串被定义为一些字符后跟一个空终止符。

如果argv[i]字符串短于2个字符,您的代码也会导致未定义的行为,因为您总是从中复制3个字符。

若要解决此问题,请使command变大并在末尾放置一个空终止符,或使用memcmp而不是strcmp。 (但是要注意memcmp,因为如果两个物体的尺寸至少不一样大,它也会导致UB)。

这里是一个可能的解决办法:

for(i = 1; i <argc; ++i) 
{ 
    if (strlen(argv[i]) < 3) 
     continue; 

    if (memcmp(argv[i], "df=", 3) == 0) 
     determineFileString(argv[i] + 3, &dataFile); 

    else if // etc. 
}    

顺便说一句,在determineFileString功能没有做任何的缓冲区大小检查(也可能缓冲区溢出)。我建议重新设计这个功能;也许它可以做一个长度检查,并在函数内部调用realloc

+0

这将是我的问题,谢谢。 – Brandon