我有一项任务。该程序将打印C中所有命令行参数的总和。我尝试编译它编译的代码但在控制台中传递参数后抛出错误。以下是代码。
/* Printing sum of all command line arguments */
#include <stdio.h>
int main(int argc, char *argv[]) {
int sum = 0, counter;
for (counter = 1; counter <= argc; counter++) {
sum = atoi(sum) + atoi(argv[counter]);
}
printf("Sum of %d command line arguments is: %d\n", argc, sum);
}
编译后输出Segmentation fault (core dumped)
错误。您的经验可以解决我的问题。
以下是我编辑的代码:
/* Printing sum of all command line arguments*/
#include <stdio.h>
#include <stdlib.h> // Added this library file
int main (int argc, char *argv[]) {
int sum = 0, counter;
for (counter = 1; counter < argc; counter++) {
// Changed the arithmetic condition
sum = sum + atoi(argv[counter]);
// Removed the atoi from sum variable
}
printf("Sum of %d command line arguments is: %d\n", argc, sum);
}
答案 0 :(得分:12)
因为你正在迭代counter == argc
,所以你将NULL
指针传递给atoi()
,这很简单,只需要依赖argv
数组有{ {1}}哨兵,并执行此操作
NULL
请注意,/* Printing sum of all command line arguments*/
#include <stdlib.h> /* For `atoi()' */
#include <stdio.h> /* For `printf()' */
int main(int argc, char *argv[])
{
int sum;
sum = 0;
for (int counter = 1; argv[counter] != NULL; ++counter) {
sum += atoi(argv[counter]);
}
printf("Sum of %d command line arguments is: %d\n", argc, sum);
}
是未定义的行为,因为atoi(sum)
是sum
并且不是有效指针。虽然int
会尝试取消引用它。另外atoi()
代表 ascii到整数,而aoti()
已经是一个整数,因此转换没有意义。
最后,为sum
添加 stdlib.h 。我知道你没有包含它,因为我在编译器上启用了警告,它警告我atoi()
是隐式定义的。 可能可以工作,但仅仅因为未定义的行为就是这样,UNDEFINED。
另外,请注意,无法知道传递的参数是否为整数,因为atoi()
无法执行错误检查。您可能希望改为使用atoi()
并检查所有值是否为整数。
所以...这就是你如何编写这个程序更强大的版本
strtol()
编辑:要解决this comment
例如,如果您通过#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int sum;
sum = 0;
for (int counter = 1; argv[counter] != NULL; ++counter) {
char *endptr;
sum += strtol(argv[counter], &endptr, 10);
if (*endptr != '\0') {
fprintf(stderr, "error: the `%d-th' argument `%s', is not a valid integer\n", counter, argv[counter]);
return EXIT_FAILURE;
}
}
printf("sum of %d command line arguments is: %d\n", argc, sum);
return EXIT_SUCCESS;
}
函数之一执行程序,则有可能argc == 0
。在这种情况下,您必须在开始循环之前进行检查,否则exec*()
将是最后一个元素之后的一个元素,即超出范围。
答案 1 :(得分:7)
指定argv[argc]
总是是空指针。你循环太多,并将这个空指针传递给atoi
,导致未定义的行为。
将循环条件更改为counter < argc
。
并且sum
已经 是一个整数,您无需将其转换为atoi
的整数。由于第一次迭代将零传递给atoi(sum)
,因此atoi
好。
答案 2 :(得分:6)
argv
的最后一个元素已定义为NULL
,第一个元素始终是程序名称。因此,您可以将代码缩减为
#include "stdio.h"
int main(int argc, char *argv[])
{
int sum = 0;
for (int i = 1; argv[i]; ++i){
sum += atoi(argv[i]);
}
printf("Sum of %d command line arguments is: %d\n", argc, sum);
}
在您的代码中,atoi(sum)
的行为以及最终迭代中归结为argv[argc]
的行为将是未定义的。
答案 3 :(得分:-2)
一个递归版本,只是为了它:)
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
static int sum;
if (*++argv == NULL)
return !printf("sum: %d argc %d\n", sum, argc - 1);
sum += atoi(*argv);
return main(argc, argv);
}
答案 4 :(得分:-2)
/* My example. Should work, though untested. */
#include <stdio.h>
int main(int argc, char *argv[])
{
int sum, index; // Generally considered better form to put them on separate lines.
sum = 0;
if(argc > 1) {
for(index = 1; index < argc; index++) {
sum += atoi(argv[index]);
}
printf("%d Command-line args\nSum = %d\n", argc, sum);
}
else {
printf("Not enough command-line args\n");
}
}
请务必尽量遵守代码的特定格式样式。如果要按名称定义样式指南,请搜索样式指南。 GNU C is a good starting point。它们将使您的代码更易于阅读,更易于调试,并帮助其他人了解其中正在发生的事情。
对上述代码进行一些更正..
/* Your code with corrections */
#include "stdio.h"
int main(int argc, char *argv[])
{
int sum=0,counter;
// 1. Normally you want to give each variable it's own line. Readability is important.
// 2. Don't initialize on declaration either. Refer to my example.
// 3. Always add spaces between operators and at the end of statements for better readability.
for(counter=1;counter<=argc;counter++)
{
// 4. atoi(sum) is unneccessary as it interprets your int sum as a const char*,
// which as far as I can tell should just give you back it's ascii value.
// It might be undefined however, so I would remove it regardless.
// 5. Your segfault issue is because you iterate over the end of the array.
// You try to access the [argc] value of the array (remember 0-based
// indexing means a size val is always 1 greater than the greatest index).
// Make 'counter<=argc' into 'counter < argc'
sum = atoi(sum) + atoi(argv[counter]);
}
printf("Sum of %d command line arguments is: %d\n", argc, sum);
}
atoi() documentation of a form.
预先警告,如果您在命令行中输入字符或字符串,您的代码仍将起作用,但行为将是奇怪的。 atoi()会将char转换为相应的ASCII decimal character index/value.
您还可以使用空值(argv []始终以argv [argc]中的NULL值终止)以结束迭代。我更喜欢使用提供的argc。
希望这对你有所帮助。如果您不理解我在这里发布的任何内容,请在线评论或搜索。
干杯!