我填充C程序以乘以2个输入向量。这是代码:
/**
* Function name: parseArguments
* Description:
* Determine what options or arguments user used
* Command-line options:
* [-h] : Show help information
* [-n] num: Determine number of threads
* file1 : Choose first file
* file2 : Choose second file
* Return value:
* 0: If parsing successful
* exit: If error
**/
static int parseArguments(int argc, char **argv, int* nthreads, char* file1, char* file2)
{
int opt;
int help=0;
extern int optind;
extern char * optarg; // (global variable) command-line options
while ((opt = getopt(argc, argv, "hn:")) != EOF)
{
switch (opt) {
//Parse option -h, -n
case 'n':
*nthreads = atoi(optarg);
break;
case 'h':
Usage();
exit(1);
break;
default:
fprintf(stderr, "Try 'mulvector -h' for more information\n");
exit(1);
}
// parse file1 & file2 arguments
// THIS IS WHAT I'M ASKING
if (optind < argc)
{
file1 = &argv[optind];
optind++;
}
if (optind < argc)
file2 = &argv[optind];
}
return 0;
}
问题在于,在我调用此函数(在main()函数中)然后退出此函数(继续main()函数)之后,2变量file1&amp; file2在执行parseArguments函数之前仍保留其旧值。我试图解决这个问题,但我没有结果......
希望你们能提供帮助,非常感谢先进!
注意: file1和file2的类型是char file1 [1024],所以我不能使用char **作为parseArguments函数的参数!
答案 0 :(得分:2)
C按值传递参数。因此,您对file1
和file2
所做的修改只是对函数内部指针的本地副本的修改。来电者看不到这些变化。
你可能想要:
file1
和file2
引用的缓冲区,或file1
和file2
的地址传递给该函数,并修改调用者看到的值。选项1如下所示:
static int parseArguments(..., char* file1, char* file2)
{
....
strcpy(file1, argv[optind]);
....
strcpy(file2, argv[optind]);
....
}
当然,这是要求缓冲区溢出。因此,您也应该明智地传递缓冲区的长度以允许代码避免溢出,例如使用strncpy
或strncat
。这里有一个很好的讨论问题:Why should you use strncpy instead of strcpy?
选项2如下所示:
static int parseArguments(..., char** file1, char** file2)
{
....
*file1 = &argv[optind];
....
*file2 = &argv[optind];
....
}
答案 1 :(得分:1)
file1 = &argv[optind];
如果要修改指针对象,则必须向函数传递指向指针的指针,而不仅仅是指针对象值。
那是:
char **file1, char **file2
而不是
char* file1, char* file2
答案 2 :(得分:0)
C是按值传递,即使对于指针也是如此。如果要更改指针,,则需要传入指向它的指针,然后取消引用指针以获取其后面的变量。
这意味着指向你的函数的双指针:
static int parseArguments (int argc,
char **argv,
int *nthreads,
char **pFile1,
char **pFile2)
并使用这些指针的地址调用它:
char *somePtr, *otherPtr;
int rc = parseArguments (..., &somePtr, &otherPtr);
它还意味着在函数内部取消引用,例如:
*pFile1 = &argv[optind];
实际上很容易让ISO解决这个问题,人们不得不模仿C必须模仿传递引用。
他们可以简单地为函数原型中的变量添加一个特殊标记,以指示它们是通过引用传递的,因此,对它们的访问在函数中是间接的。
这是否真的发生过,很难说。
关于你的评论:
注意:file1和file2的类型是char file1 [1024],所以我不能使用char **作为parseArguments函数的参数!
如果要传入无法修改的缓冲区地址,则必须将内存转移到该缓冲区(并忽略上面的注释),例如:
strcpy (file1, argv[optind]);
虽然你可能想要预先检查长度以防止缓冲区溢出,或者使用更安全的边界检查内存复制功能。
答案 3 :(得分:0)
因为您更改指针的地址,而不是值。
你有办法:
parseArguments(..., &charPointer1, &charPointer2)
答案 4 :(得分:0)
如果file1
和file2
指向有效内存,请将argc
个元素所指向的内存内容复制到file1
和file2的位置points to, but assigning
argc`的元素&#39;地址。
为此,请更换作业
file1 = &argv[optind];
通过复制操作
strcpy(file1, argv[optind]);
但是这样做有风险,因为在parseArgument()
内部,我不知道已为file
和file2
分配了多少内存。
要绕过这个传递给parseArguments
那些大小如下:
static int parseArguments(int argc, char **argv, int* nthreads,
char* file1, size_t size1,
char* file2, size_t size2)
{
...
memset(file1, 0, size1);
strncpy(file1, argv[optind], size1 - 1);